纯函数是否只有一种可能的实现?

时间:2019-02-17 20:58:39

标签: functional-programming ocaml

在下面的图片中有一个简短的解释,为什么纯函数似乎只有一种可能的实现。
我并没有真正的主意,因为例如(++) : ('a -> 'b) -> ('a -> 'b) -> 'a -> 'b可以由{ {1}}或
let (++) (f: ('a -> 'b)) (g: ('a -> 'b)) x = f x
该图像只是错误的还是我在这里错过了什么?

enter image description here

2 个答案:

答案 0 :(得分:2)

如果您考虑刚才给出的反例,则图像是错误的。我认为图片的作者没有考虑类型注释的可能性。

实际上是

  • 没有类型注释和
  • 所有参数都是多态的,或在多态类型上起作用,
  • 您不考虑存在=或<>之类的多态运算符 (否则是错误的,因为<>和=具有相同的类型和不同的实现),

然后只有一个纯粹的函数签名实现。

(您可能通过说出可用于定义该功能的唯一内容就是:

  • 可以内联的相同类型的纯函数,因此您可以忽略
  • match-patterns和let,图像的参数为true
  • 笛卡尔积(让f a b = a,b)
  • 功能组成
  • 无限递归
  • 也许我忘记了其他事情,但是您可以列出详尽的清单

,可以从输出和输入类型中猜测所使用的这些的组合。 )

答案 1 :(得分:2)

你是对的。即使没有类型注释,附加的图像也不正确。

首先,重要的是要考虑在此处假设实现的哪种“平等”。让我们考虑以下示例。

  1. (@@)是否等于(@@+)

    let ( @@ ) f x = f x
    let ( @@+ ) f x =
      let _ = 42 in
      f x
    
  2. (|>)是否等于(|>+)

    let ( |> ) x f = f x
    let ( |>+ ) x f = f @@ x
    
  3. (%)是否等于(%+)

    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来显示。