4

次のプロファイルを使用する関数を実装するように依頼されました。

maybe_divide :: Maybe Integer -> Maybe Integer -> Maybe Integer

そして、次のように応答します。

> maybe_divide (Just 5) (Just 2) 
Just 2
> maybe_divide (Just (-5)) (Just 2) 
Just (-3)
> maybe_divide (Just (-5)) (Just 0) 
Nothing
> maybe_divide Nothing (Just 1) 
Nothing
> maybe_divide (Just 1) Nothing
Nothing

以下のように書いたのですが、コンパイルできません。何か提案はありますか?

maybe_divide :: Maybe Integer -> Maybe Integer -> Maybe Integer
maybe_divide x y = case x of
    Just x' -> case y of 
        Just y'
            | y' == 0 -> Nothing  
            | otherwise -> x' `div` y'
    Nothing -> Nothing 
4

4 に答える 4

7

発生しているエラーを投稿する必要がありますが、

x' `div` y'

は typeIntegerであり、 notMaybe Integerです。おそらく、これを でラップする必要がありますJust

于 2013-04-25T05:24:29.323 に答える
6

Justここで成功した結果をラップする必要があります。

... | otherwise -> Just (x' `div` y')
于 2013-04-25T05:24:20.603 に答える
4

Maybeこれを行う良い方法は、Monad インスタンスを次のように使用することだと思います。

maybe_divide x y = do
   a <- x
   b <- y
   if b == 0 
     then fail "Division by zero" 
     else return (a/b)

これにより、面倒な s のチェックのほとんどが不要にNothingなり、ゼロ除算のチェックという主な業務に取りかかることができます。

Maybe モナドでは、fail "error message"実際にはNothing;になります。エラー メッセージは破棄さ"Division by zero"""ます。

Maybe モナドでは、 return「Just で包む」という意味です。


エラー チェックを行う必要がない場合は、適用可能なインスタンスを使用できます。

import Control.Applicative -- at the top of your code

maybe_multiply x y = (*) <$> x <*> y

それは私が美学的に喜ばしいことだと思います。

これは、Monad に一致する Applicative インスタンスの場合f <$> x <*> y <*> z

do 
  a <- x
  b <- y
  c <- z
  return $ f a b c
于 2013-04-25T13:44:23.400 に答える