假设我有一个功能
foo :: a -> b -> c -> d -> e
foo a b c d = somefn a b c d
以及一些回复我a, b, c and d
的函数
getA :: a
getB :: b
getC :: f c
getD :: d
仅返回c
的函数返回带有c
现在我打电话给网站
callfoo = foo getA getB getC getD
显然不会起作用,因为getC返回c的仿函数而不是c本身。所以唯一的方法似乎是
callfoo = (foo getA getB) <$> getC <*> getD
除了简单对foo
的调用在此处丢失之外,签名也会更改为callfoo :: f e
。
保持简单的一种方法是(extract getC)
,但这是邪恶的,会让你进入Haskell-hell的特殊区域。我知道。
我的一般问题是: 我如何处理我主要使用非函数值的情况,但突然之一的值也迫使我提升所有其他值?
答案 0 :(得分:1)
您可以使用do
语法:
do
c <- getC
return (foo getA getB c getD)
如果您启用ApplicativeDo
,则会使用有效的fmap
表单,而不是可能效率低下的>>=
和return
表单。
有quasiquoter on Hackage for idiom brackets可以让你写
[i| foo (pure getA) (pure getB) getC (pure getD) |]
否则,几乎没有糖。有许多方法可以用现有的组合器来拼写你的操作,这些方法通常在所有情况下通用和紧凑之间进行权衡。一些例子包括:
flip (foo getA getB) getD <$> getC
(\c -> foo getA getB c getD) <$> getC
foo getA getB <$> getC <*> pure getD
foo <$> pure getA <*> pure getB <*> getC <*> pure getD