Jon*_*nas 9 haskell currying pointfree
我试图实现这个功能
every :: (a -> IO Bool) -> [a] -> IO Bool
Run Code Online (Sandbox Code Playgroud)
这是这个问题的主题.我没有明确的递归尝试这样做.我想出了以下代码
every f xs = liftM (all id) $ sequence $ map f xs
Run Code Online (Sandbox Code Playgroud)
我的功能不起作用,因为它不是懒惰的(问题中需要),所以没有赞成在那里:-).
但是,我并没有就此止步.我试图使功能无点,以便它更短(甚至更冷).由于参数f
和xs
在我刚把他们表达了最后的:
every = liftM (all id) $ sequence $ map
Run Code Online (Sandbox Code Playgroud)
但是这没有按预期工作,事实上它根本不起作用:
[1 of 1] Compiling Main ( stk.hs, interpreted ) stk.hs:53:42: Couldn't match expected type `[m a]' against inferred type `(a1 -> b) -> [a1] -> [b]' In the second argument of `($)', namely `map' In the second argument of `($)', namely `sequence $ map' In the expression: liftM (all id) $ sequence $ map Failed, modules loaded: none.
这是为什么?我的印象是,可以简单地删除尾随函数参数,这基本上就是currying的内容.
Dav*_*ave 25
$的定义是
f $ x = f x
Run Code Online (Sandbox Code Playgroud)
让我们完全括起你的功能:
every f xs = (liftM (all id)) (sequence ((map f) xs))
Run Code Online (Sandbox Code Playgroud)
和你的咖喱版:
every = (liftM (all id)) (sequence map)
Run Code Online (Sandbox Code Playgroud)
正如您所注意到的,这些并不完全相同.只有在应用的最后一个事物时才能删除尾随函数参数.例如,
f x = g c x
Run Code Online (Sandbox Code Playgroud)
实际上是
f x = (g c) x
Run Code Online (Sandbox Code Playgroud)
并且(gc)对x的应用是最后的,所以你可以写
f = g c
Run Code Online (Sandbox Code Playgroud)
应用程序运算符$的一种模式是它经常成为组合运算符.在免费版本中.这是因为
f $ g $ x
Run Code Online (Sandbox Code Playgroud)
相当于
(f . g) $ x
Run Code Online (Sandbox Code Playgroud)
例如,
every f xs = liftM (all id) $ sequence $ map f xs
Run Code Online (Sandbox Code Playgroud)
可以变成
every f xs = (liftM (all id) . sequence . map f) xs
Run Code Online (Sandbox Code Playgroud)
此时你可以删除xs:
every f = liftM (all id) . sequence . map f
Run Code Online (Sandbox Code Playgroud)
消除参数f更加困难,因为它在合成运算符之前应用.让我们使用http://www.haskell.org/haskellwiki/Pointfree中点的定义:
dot = ((.) . (.))
Run Code Online (Sandbox Code Playgroud)
有点,这是
(f `dot` g) x = f . g x
Run Code Online (Sandbox Code Playgroud)
而且正是我们需要让每一个完全无点的:
every = (liftM (all id) . sequence) `dot` map
Run Code Online (Sandbox Code Playgroud)
遗憾的是,由于Haskell类型系统的限制,这个需要一个显式类型签名:
every :: (Monad m) => (a -> m Bool) -> [a] -> m Bool
Run Code Online (Sandbox Code Playgroud)