Haskell中的通用'解包'功能?

时间:2012-02-27 06:45:24

标签: haskell

当我在一个值上使用fmap时,它基本上“取消”该值,将该函数应用于该值,然后将其重新装箱。

例如:

-- returns Just 8
fmap (+3) (Just 5)

是否有任何函数可以在没有重新装箱的情况下为我提供价值?

-- returns 8
fmap_2 (+3) (Just 5)

当然,我不知道这对数组有什么用处,但对于初学者来说,它对EitherMaybe有用。我也可以用它轻松混合Monads:

-- myfunc :: Maybe Int

-- if myfunc returned a Just, show it and then print it. Otherwise, print 'Nothing'.
putStrLn . fmap show $ myfunc

还有另一种混合Monads的标准方法吗?

3 个答案:

答案 0 :(得分:9)

提取Maybe使用maybe

maybe 0 (+3) $ Just 5
>>> 8
maybe 0 (+3) Nothing
>>> 0

只有在获得fromJust时才应将Nothing视为异常情况。如果没有充分的理由,不要养成破坏程序的习惯。 MaybeEither正是为了帮助您避免这种情况。

对于Either,有一个函数either

either (*2) (+2) $ Left 3
>>> 6
either (*2) (+2) $ Right 3
>>> 5

请注意,在正确的代码中,您不需要经常提取monad。关于它们,这是一个完整的观点,Haskell必须提供使用monadic值所需的所有工具,就像它们被提取一样。

答案 1 :(得分:5)

所有仿函数不能存在此函数。即使对于像Maybe这样的简单版本,如果你有一个Nothing,也行不通。对于IO,这将允许您在程序中执行任意IO并且明显不安全。最后,对于一些稍微怪异的函子(比如(->) e,它只是一个带有e类型参数的函数),这甚至没有任何意义。

但是,对于 仿函数的某些类型,此函数存在。例如,有一个名为fromJust的函数,其类型为Maybe a -> a。但是,如果将此函数传递给Nothing,则会出现运行时错误。

因此,对于某些也是Functor实例的类型,可能存在这样的函数,但它对Functor类本身没有意义。

答案 2 :(得分:2)

导入Control.Comonad(extract