我想知道Haskell是否跟踪天气,函数是一个函数组合,即我可以定义一个与此类似的函数吗?:
compositionSplit f.g = (f,g)
答案 0 :(得分:18)
不,这是不可能的。
例如,
f1 = (+ 1) . (+ 1) :: Int -> Int
与
功能相同f2 = subtract 1 . (+ 3) :: Int -> Int
和引用透明度要求equals可以替换为equals,所以如果compositionSplit
可以,那么
f1
和f2
生成相同的结果,因为这是相同的功能,但compositionSplit f1 = ((+ 1), (+1))
和compositionSplit f2 = (subtract 1, (+ 3))
需要compositionSplit
的规范。
答案 1 :(得分:4)
可以。在严格解释的非编译实现中,您可以将函数表示为
data Function = F Source | Compo Function Function
然后你只需要定义
compositionSplit (Compo f g) = Just (f,g)
compositionSplit _ = Nothing
此类实现会将函数相等(w.r.t.引用透明度)视为intensional,而不是extensional相等。由于语言本身没有说明AFAIK函数的相等性,所以这不应该影响任何事情(除了性能)。
在编译的实现中,这也可以实现,例如通过为内存中的每个对象维护来源。
AndrewC给出了一个胜利的反驳论点:对于两个值a=f.(g.h)
和b=(f.g).h
,如果我们想将它们视为相等的值 - 我们通常在Haskell中做 - fst.unJust.deCompo
将产生两种不同的结果,打破参考透明度。所以它不能成为纯FP范式的一部分。在这两种情况下,我们必须返回一些我们可以合理地认为是同等价值的东西,如果不打破纯度,我们就无法将它分开。也许这样的事情可能存在于一些不纯的单子中,但这不是OP所要求的,遗憾的是。 :)所以这个答案是错误的。