Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 折叠、函数合成、单子和惰性,哦,天哪?_Haskell_Monads_Fold_Function Composition - Fatal编程技术网

Haskell 折叠、函数合成、单子和惰性,哦,天哪?

Haskell 折叠、函数合成、单子和惰性,哦,天哪?,haskell,monads,fold,function-composition,Haskell,Monads,Fold,Function Composition,我很困惑。我可以这样写: import Control.Monad main = print $ head $ (foldr (.) id [f, g]) [3] where f = (1:) g = undefined 输出为1。这是有道理的,因为它减少到: main = print $ head $ ((1:) . undefined . id) [3] main = print $ head $ (1:) ((undefined . id) [3]) main =

我很困惑。我可以这样写:

import Control.Monad

main = print $ head $ (foldr (.) id [f, g]) [3]
  where f = (1:)
        g = undefined
输出为
1
。这是有道理的,因为它减少到:

main = print $ head $ ((1:) . undefined . id) [3]
main = print $ head $ (1:) ((undefined . id) [3])
main = print $ head $ 1 : ((undefined . id) [3])
main = print $ 1
但如果我使用一种模糊相似的一元技术,它的工作原理就不一样了:

import Control.Monad

main = print $ (foldr (<=<) return [f, g]) 3
  where f = const Nothing
        g = undefined
但是,翻转构图顺序:

import Control.Monad

main = print $ (foldr (>=>) return [f, g]) 3
  where f = const Nothing
        g = undefined
完成了预期的短路并没有产生任何结果

main = print $ (const Nothing >=> undefined >=> return) 3
main = print $ (const Nothing 3) >>= undefined >>= return
main = print $ Nothing >>= undefined >>= return
main = print $ Nothing

我想比较这两种方法可能是比较苹果和桔子,但你能解释一下区别吗?我认为在第一个参数中,
f的绑定可能是严格的

Just v >>= f = f v
Nothing >>= f = Nothing
所以当你尝试的时候

Just v >>= undefined >>= \_ -> Nothing
你击中

undefined v >>= \_ -> Nothing
实现需要找出
未定义的v
还是
只是某个东西
,以查看使用
(>>=)
的哪个等式

另一方面,

Nothing >>= undefined

在不查看
(>>=)

的第二个参数的情况下确定结果,这取决于您使用的单子以及其
(>=)
运算符的定义方式

Maybe
的情况下,
(>>=)
在其第一个参数中是严格的,正如Daniel Fischer解释的那样

下面是一些其他单子的结果

> :set -XNoMonomorphismRestriction
> let foo = (const (return 42) <=< undefined <=< return) 3
> :t foo
foo :: (Num t, Monad m) => m t
IO:严格

> foo :: IO Integer
*** Exception: Prelude.undefined
> Control.Monad.Cont.runCont foo id
*** Exception: Prelude.undefined
读者:懒惰

> Control.Monad.Identity.runIdentity foo
42
> Control.Monad.Reader.runReader foo "bar"
42
Writer:既有懒惰的变体,也有严格的变体

> Control.Monad.Writer.runWriter foo
(42,())
> Control.Monad.Writer.Strict.runWriter foo
*** Exception: Prelude.undefined
状态:也有严格版本和惰性版本

> Control.Monad.State.runState foo "bar"
(42,"*** Exception: Prelude.undefined
> Control.Monad.State.Strict.runState foo "bar"
*** Exception: Prelude.undefined
续:严格

> foo :: IO Integer
*** Exception: Prelude.undefined
> Control.Monad.Cont.runCont foo id
*** Exception: Prelude.undefined