鉴于这两个程序(用JavaScript编写)…如何根据其实现派生一个过程的HM类型?
// comp :: (b -> c) -> (a -> b) -> (a -> c)
const comp = f=> g=> x=> f (g (x))
// comp2 :: (c -> d) -> (a -> b -> c) -> (a -> b -> d)
const comp2 = comp (comp) (comp)
我的问题是如何导出comp2
的Hindley-Milner Type没有引用comp
的实施
如果我们知道comp
的实现,它很容易和hellip;我们可以通过整个评估使用替代模型来得到扩展的表达式hellip;
comp (comp) (comp)
= (f => g => x => f (g (x))) (comp) (comp)
= x => comp (comp (x))
= y => comp (comp (y))
= y => (f => g => x => f (g (x))) (comp (y))
... keep going until ...
= f=> g=> x=> y=> f (g (x) (y))
环一鼎。扩展评估匹配comp2
的类型。没有人印象深刻。
// comp2 :: (c -> d) -> (a -> b -> c) -> (a -> b -> d)
const comp2 = f=> g=> x=> y=> f (g (x) (y))
但是,如果我们只知道comp
的型并做不知道它实施?我是否可以在comp
的类型上进行某种替换/评估来代替comp2
的类型?
只有这样,问题变得更加困难...... (至少对我来说)
// comp :: (b -> c) -> (a -> b) -> (a -> c)
// comp2 :: ???
const comp2 = comp (comp) (comp)
有一定的办法吧?这不是什么algebraic data types是关于什么?
让我们来看一个简单的例子来阐明我的问题:如果我们有像add
和map
&hellip功能;
// add :: Number -> Number -> Number
// map :: (a -> b) -> [a] -> [b]
如果我们想用map
和add
定义一个函数,我们可以计算出类型系统不知道add
或map
的实施
// add :: Number -> Number -> Number
// map :: (a -> b) -> [a] -> [b]
// add6 :: Number -> Number
let add6 = add (6)
// mapAdd6 :: [Number] -> [Number]
let mapAdd6 = map(add6)
这是因为它真的很强大允许你推理你没有做的代码,而不必深入实施(尽可能多的)
但是,试图与comp2
例子做的时候,我卡住相当快
// comp :: (b -> c) -> (a -> b) -> (a -> c)
// comp2 :: ??
const comp2 = comp (comp) (comp)
// initial type
(b -> c) -> (a -> b) -> (a -> c)
// apply to comp once ... ???
[(b -> c) -> (a -> b) -> (a -> c)] -> (a -> b) -> (a -> c)
// apply the second time ... ???
[(b -> c) -> (a -> b) -> (a -> c)] -> [(b -> c) -> (a -> b) -> (a -> c)] -> (a -> c)
// no... this can't be right
HOW TO辛德雷MILNER
精彩的解释。谢谢^ _ ^ – naomik