为什么这不会抛出任何类型的错误?

jij*_*esh 1 haskell type-inference

我正在尝试从其中一个博客中获取一些代码段,然后我注意到以下代码

f :: Int -> [Int]
f x = [1+x,2*x]

test :: IO ()
test = putStrLn . show $ return 5 >>= f >>= f
Run Code Online (Sandbox Code Playgroud)

执行时我正在[7,12,11,20].为什么第二个'f'函数调用不是抛出类型错误?这是List Monad的相关内容吗?

dav*_*420 6

这正是因为列表是monad.你有

return 5 >>= f >>= f
Run Code Online (Sandbox Code Playgroud)

在monad列表中(>>=) = flip concatMap,所以它是一样的

concatMap f $ concatMap f $ return 5
Run Code Online (Sandbox Code Playgroud)

也在monad列表中return x = [x],所以我们有

concatMap f $ concatMap f [5]
Run Code Online (Sandbox Code Playgroud)

现在,concatMap g x = concat (map g x)我们可以将其扩展到

concat $ map f $ concat $ map f [5]
Run Code Online (Sandbox Code Playgroud)

并评估它

concat $ map f $ concat $ [[6, 10]]
concat $ map f $ [6, 10]
concat $ [[7, 12], [11, 20]]
[7, 12, 11, 20]
Run Code Online (Sandbox Code Playgroud)

那有意义吗?