fre*_*low 4 haskell list-comprehension
可以使用更高阶函数简化以下函数,Monads或者你有什么用?
cube list = [(x, y, z) | x <- list, y <- list, z <- list]
Run Code Online (Sandbox Code Playgroud)
该函数只是创建列表元素的所有三重排列的列表.例如:
> cube [1..2]
[(1,1,1),(1,1,2),(1,2,1),(1,2,2),(2,1,1),(2,1,2),(2,2,1),(2,2,2)]
Run Code Online (Sandbox Code Playgroud)
Edw*_*ang 10
从比尔的答案来看,因为这是代码使用列表monad,我们可以使用"applicative"样式来做"具有更高阶函数".这是否是一个好主意留给工程师的练习.
import Control.Applicative
cube :: [a] -> [b] -> [c] -> [(a,b,c)]
cube x y z = (,,) <$> x <*> y <*> z
Run Code Online (Sandbox Code Playgroud)
虽然它为您提供了列表而不是元组,但您可以使用Control.Monad中的sequence函数:
> let list = [1..2]
> sequence [list, list, list]
[[1,1,1],[1,1,2],[1,2,1],[1,2,2],[2,1,1],[2,1,2],[2,2,1],[2,2,2]]
Run Code Online (Sandbox Code Playgroud)
该sequence功能很整洁,因为虽然它的"预期"目的是获取一个动作列表,按顺序执行它们,并将它们的结果返回到列表中,在列表中使用它monad为您提供免费组合.
> sequence $ replicate 3 "01"
["000","001","010","011","100","101","110","111"]
Run Code Online (Sandbox Code Playgroud)
实际上,您的列表理解是List monad的用法.
另一种写这个的方法是:
cube :: [a] -> [(a,a,a)]
cube list = do
x <- list
y <- list
z <- list
return (x, y, z)
Run Code Online (Sandbox Code Playgroud)
这不是一个真正的答案,但无论如何我都要提出建议.主要是为了疯狂.
import Control.Monad
import Control.Monad.Instances
cube :: [a] -> [(a, a, a)]
cube = join . join $ liftM3 (,,)
Run Code Online (Sandbox Code Playgroud)
玩得开心.:)