fmap的反向作用是什么?

时间:2018-11-01 10:12:26

标签: haskell maybe

我有一个函子链,有时需要将我的值包装在Maybe中:

module Funct where 
(>>?) :: Maybe a -> (a -> Maybe b) -> Maybe b
(Just a) >>? f = f a
Nothing >>? _ = Nothing


f1 :: Int -> Maybe Bool
f1 a = if a > 2 then Just (a `mod` 2 == 0)  else Nothing

f2 :: Bool ->  Char
f2 b = if b then 'a' else 'b'

f3 :: Char -> Maybe Int
f3 c = if c == 'a' then Just 1 else Nothing

fm :: Int -> Maybe Int
fm x = f1 x >>? f2  >>? f3
                 ^ 
                 Is there a reverse method for fmap particular for Maybe 
                 or do I have to implement it?

已实施

myWrapper :: Char->Maybe Char
myWrapper c = Just c

fm x = f1 x >>? myWrapper . f2 >>? f3  -- is there any built in way more concise?

我问是因为链接时,我想您也需要像Either这样的其他monad的包装器。

3 个答案:

答案 0 :(得分:6)

  

(是否有任何更简洁的内置方法?)

确定:

myWrapper = Just

或内联:

fm x= f1 x>>? Just . f2 >>? f3

数据构造函数可以看作是普通函数,因此您可以将它们与其他函数组成。

答案 1 :(得分:5)

generated file with funny characters,其优先级与(>>=)相同:

fm x = f1 x <&> f2 >>= f3

答案 2 :(得分:2)

  

我问是因为链接时,我想您也需要像Either这样的其他monad的包装器。

正确。每个MaybeEither之类的类型构造函数都需要自己定义诸如>>=return之类的东西,但这就是类型类实例的确切含义:类型类的定义专用于特定类型构造函数的方法。例如,

class Monad m where
    return :: a -> m a
    (>>=) :: m a -> (a -> m b) -> m b

instance Monad Maybe where
    return = Just
    Nothing >>= _ = Nothing
    (Just x) >>= f = f x

-- This looks similar to the Maybe instance because in some sense,
-- Maybe is just a special case of Either: Maybe ~ Either ()
instance Monad (Either a) where
    return = Right
    (Left x) >>= _ = Left x
    (Right x) >>= f = f x

然后可以以一种适用于任何 monad的方式编写您的fm函数,而不仅仅是Maybe

fm :: Maybe m => Int -> m Int
fm x = f1 x >>= return . f2  >>= f3