在下面的图片中有一个简短的解释,为什么纯函数似乎只有一种可能的实现。
我并没有真正的主意,因为例如(++) : ('a -> 'b) -> ('a -> 'b) -> 'a -> 'b
可以由{ {1}}或
let (++) (f: ('a -> 'b)) (g: ('a -> 'b)) x = f x
该图像只是错误的还是我在这里错过了什么?
答案 0 :(得分:2)
如果您考虑刚才给出的反例,则图像是错误的。我认为图片的作者没有考虑类型注释的可能性。
实际上是
然后只有一个纯粹的函数签名实现。
(您可能通过说出可用于定义该功能的唯一内容就是:
,可以从输出和输入类型中猜测所使用的这些的组合。 )
答案 1 :(得分:2)
你是对的。即使没有类型注释,附加的图像也不正确。
首先,重要的是要考虑在此处假设实现的哪种“平等”。让我们考虑以下示例。
(@@)
是否等于(@@+)
?
let ( @@ ) f x = f x
let ( @@+ ) f x =
let _ = 42 in
f x
(|>)
是否等于(|>+)
?
let ( |> ) x f = f x
let ( |>+ ) x f = f @@ x
(%)
是否等于(%+)
?
let ( % ) f g x = f (g x)
let ( %+ ) p q r = p (q r)
如果(@@)
不等于(@@+)
,那么我们可以构造函数bool -> bool
的第五个实现,例如(fun x -> let _ = 42 in true)
。
因此,图像的作者可能不希望通过功能(或代码)来区分函数,而是通过其他元素(例如行为)(如duck test或数学函数的相等性)来区分。 / p>
仍然,图像不正确。该图像声称“对于签名中没有任何具体类型的纯函数,只有一种可能的实现”,但没有。例如,没有纯函数'a -> 'b
。可以通过the Curry–Howard correspondence来显示。