这里是Haskell的新手。
我想写:
take 1 $ take 2 [1, 2, 3] -- = 1
reversed,例如此伪代码:
[1, 2, 3] -> take 2 -> take 1 -- = 1
在Clojure中,我们可以使用:
(->> [1 2 3]
(take 2)
(take 1)) ;=> (1)
Clojure这样做是因为->>
是一个将表达式重写为(take 1 (take 2 [1 2 3]))
的宏,但是因为Haskell是惰性的并且有局部和诸如此类的东西,所以看起来应该很容易。
我想这样做,是因为先获取数据,然后读取函数以便执行它们是读取代码的一种好方法。我被Clojure宠坏了!
类似于面向对象语言中的var.action1().action2()
等的流畅接口/链接模式。
我想这在Template Haskell中是可能的,但是肯定有一种我不知道的内置方法来做到这一点?谢谢!
有(&)
,您需要从Data.Function
导入。
> import Data.Function
> [1,2,3] & take 2 & take 1
[1]
如果您确实不喜欢导入该模块,则定义就是(&) = flip ($)
。
chepner的答案完全是正确的。
还有更多滥用Haskell语法的技巧,但是不应下面的代码可用于任何严肃的应用程序。
RebindableSyntax
破坏了用户对标准结构含义的期望。可变参数函数具有可怕的类型推断,错误报告和特殊情况(可以通过不费吹灰之力来缓解这些问题,但从未完全解决)。
符号do {x ; y}
是x >> y
的糖,并且RebindableSyntax
扩展名允许您重新绑定(>>)
。您可以将其重新定义为(反向)函数组成,例如:
y :: [Int]
y = [1,2,3] & do
take 2
take 1
where
(>>) = flip (.)
您可以使用类型类将(->>)
定义为可变函数。
z :: [Int]
z = (->>) [1,2,3]
(take 2)
(take 1)
class App a b where
(->>) :: a -> b
instance (a ~ a', App b c) => App a ((a' -> b) -> c) where
(->>) x y = (->>) (y x)
instance {-# OVERLAPPABLE #-} (a ~ a') => App a a' where
(->>) = id
要点:https://gist.github.com/Lysxia/3461f489cc5057ea089e23a4eede375a