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