2012-02-27 25 views
3

当我使用fmap超过一个值时,它实质上“解开”该值,将该函数应用于该值并将其备份。Haskell中的泛型'unwrap'函数?

例如:

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

是否有给我不拳击回来了价值的功能?

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

当然,我不知道如何做到这一点的阵列工作,但它会为Either S和Maybe S,对于初学者来说是有用的。我也可以用它来轻松地混合Monad:

-- myfunc :: Maybe Int 

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

或者是否有另一种混合Monads的标准方式?

+5

不,没有混合单子的标准方式。不可能有。 Monad不通勤。 然而,* some * monads可以混合在他们自己的特殊方式。将这种特殊的monad混合方式封装起来的方法称为monad变压器。有几个单子变压器的图书馆和广泛的文献。只是谷歌“monad变压器”。 – 2012-02-27 07:24:32

+0

看一看:[如何从monadic action中提取价值?](http://stackoverflow.com/questions/8567743/how-to-extract-value-from-monadic-action) – 2012-02-27 07:24:35

回答

9

对于提取Maybe使用maybe

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

得到一个Nothing只有当你应该使用fromJust必须被视为异常情况。如果没有充分的理由,不要冒着破坏程序的习惯。 MaybeEither是否准确地帮助您避免这种情况。

对于Either有一个函数either

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

请注意,正确的代码,你将不必经常提取单子。这对他们来说有点重要,Haskell必须提供所有可能需要的工具来处理monadic值,就好像它们被提取一样。

+4

也有'fromMaybe :: a - >也许一个 - > a' – rampion 2012-02-27 10:54:59

+0

+1段 – amindfv 2012-02-27 16:00:45

5

此函数不能存在所有仿函数。即使对于像Maybe这样的简单应用,如果您有Nothing,也不会起作用。对于IO,这可以让你在你的程序中执行任意的IO操作,并且绝对不安全。最后,对于一些稍微有些怪异的函子(如(->) e,它只是一个函数,参数类型为e),这甚至没有任何意义。

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

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

2

import Control.Comonad(extract