【问题标题】:Functional JavaScript: What is the Hindley-Milner Type Signature of Compose?函数式 JavaScript:Compose 的 Hindley-Milner 类型签名是什么?
【发布时间】:2017-10-27 19:02:06
【问题描述】:

以下对 compose 函数的 Hindley-Milner 类型签名的尝试是否正确?

// compose :: (f -> [f]) -> (f -> f -> f) -> [f] -> f
const compose = (...fns) => fns.reduce((f,g) => (...args) => f(g(...args)));

【问题讨论】:

  • 你是怎么得出那个类型签名的?
  • 我认为 Hindley-Milner 系统只适用于固定数量

标签: javascript functional-programming hindley-milner


【解决方案1】:

不,这是不正确的。您的 compose 函数将一组函数作为输入,并生成一个(组合)函数作为输出,因此签名显然是错误的。另一方面,我认为不可能使用 Hindley-Milner 类型系统编写该函数,除非您假设 fns 中的所有函数都是同一类型的一元函数:a -> a(即endomorphisms) 的数组。

compose :: [a -> a] -> (a -> a)

JavaScript 是动态类型的,所以它实际上允许fns 中的每个函数是不同的类型(JS 不要求数组是同质的)。这意味着您可能需要发明一些新语法,以便按照您的方式表达compose 的类型。以下是Ramda(JS 的函数式实用程序库)如何描述R.compose 的类型:

((y → z), (x → y), …, (o → p), ((a, b, …, n) → o)) → ((a, b, …, n) → z)

它使用 语法来表示可变参数函数。参数列表中最右边的函数是((a, b, …, n) → o) 类型,这意味着它是一个返回o 的可变参数函数。这个o 然后被用作下一个函数的输入,该函数的类型为(o → p)。这将在参数列表中继续向下,直到最左边的函数的类型为 (y → z),其中 z 成为调用返回函数的结果类型:((a, b, …, n) → z)

【讨论】:

  • 太棒了!!!我一直想破译 Ramda 的作曲符号
【解决方案2】:

二元函数组合的类型更容易用 Hindley-Milner 表示法表示:

//    compose :: (b -> c) -> (a -> b) -> a -> c
const compose = f => g => x => f (g (x));

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-25
    • 1970-01-01
    • 2013-03-07
    • 1970-01-01
    • 2019-03-06
    • 1970-01-01
    • 2012-11-24
    • 2014-03-30
    相关资源
    最近更新 更多