2012-02-27 61 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