简体   繁体   English

函数Haskell的类型推断

[英]Type Inferring of function Haskell

Im trying to infer the type of: 我正在尝试推断以下类型:

((.) foldr)

The type i manually infer differs from the one ghci infer. 我手动推断的类型不同于一个ghci推断。 Here's what i do: 这是我的工作:

(.) ::    ( b  ->    c) -> (a->b)->a->c
foldr:: (a'->b'->b')->b'->[a']->b'

Now my first doubt. 现在我的第一个疑问。 Foldr has to unify with b->c foldr has to unify with (b->c) but there are more than one way to make it happen; 文件夹必须与b-> c统一文件夹必须与(b-> c)统一,但是有多种方法可以实现它。 like 喜欢

b ~ (a'->b'->b')
c ~ b'->[a']->b'

or.. 要么..

b ~ (a'->b'->b')b'->[a']
c ~ b'

How do i know which to take? 我怎么知道要服用哪一种?

Doing different examples in ghci i arrived to the conclusion that haskell tries to unify types in a non greedy fashion for the first argument (This conclusion is totally experimental and can be totally wrong, maybe its the reason i arrive to a wrong type for the function, but is what i thought of the type inferences ive tried on haskell). 在ghci中做不同的例子,我得出了一个结论,即haskell试图以非贪婪的方式为第一个参数统一类型(该结论完全是实验性的,可能是完全错误的,也许这是我对函数得出错误类型的原因,但我想到的是我在haskell上尝试过的类型推断。 So, assuming this is true the configuration haskell tries to unify first is: 因此,假设这是正确的,则配置haskell首先尝试统一为:

b ~ (a'->b'->b')
c ~ b'->[a']->b'

So now.. 所以现在

(.)foldr :: (a->b)->a->c

Substituting b and c: 替换b和c:

    (.)foldr :: (a-> (a'->b'->b') )->a->b'->[a']->b' 

Which is close enough the only problem i have are the parentheses in the expression (a'->b'->b') Why can i remove them when you cannot remove those in the original foldr, and the function is gonna be an input for foldr. 哪一个足够接近,我唯一的问题是表达式中的括号(a'-> b'-> b')为什么当您无法删除原始文件夹中的括号且函数将作为输入时,为什么要删除它们?用于文件夹。 Why after applying the composition functor you can use partial application? 为什么在应用成分函子后可以使用部分应用程序? Is there a rule for that? 有规则吗? Also i would like if someone coudl confirm or deny the "non greedy" type matching.. 我也想如果有人能确认或拒绝“非贪婪”类型匹配。

The associativity of -> ->的关联

In Haskell the only type of function is a -> b , which is a function that takes an a and "returns" a b . 在Haskell中,唯一的函数类型是a- a -> b ,这是一个接受a并“返回” a b的函数。 For this reason a function type of: 因此,函数类型为:

a -> b -> c

is implicitly: 隐式地:

a -> (b -> c)

that is a function that takes an a and returns a function that takes a b and returns a c . 那是一个接受a并返回一个接受b并返回c的函数的函数。 You just have to remember that -> is right associative . 您只需要记住->正确的关联 This is the "mechanism" that allows currying. 这是允许进行欺骗的“机制”。

Answers 答案

How do i know which to take? 我怎么知道要服用哪一种?

So, in your example: 因此,在您的示例中:

foldr:: (a' -> b' -> b') -> b' -> [a'] -> b'

becomes: 变为:

foldr:: (a' -> b' -> b') -> (b' -> ([a'] -> b'))

As you can see the only way to infer a type a -> b is by assigning (a'->b'->b') to a and (b'->([a']->b')) to b . 如您所见,推断类型a- a -> b的唯一方法是将(a'->b'->b')分配给a(b'->([a']->b')) b


Why can I remove them when you cannot remove those in the original foldr, and the function is gonna be an input for foldr? 当您无法删除原始文件夹中的功能并且该功能将作为文件夹的输入时,为什么要删除它们?

Because after the function composition, the type is: 因为在函数组成之后,类型是:

(a -> (a' -> b' -> b')) -> a -> b' -> [a'] -> b'
-- ^^^^^^^^^^^^^^^^^^^^

Let's focus on the first part: 让我们专注于第一部分:

(a -> (a' -> b' -> b'))

this is, for the right associativity of -> , equal to: 对于->的正确关联性,等于:

(a -> (a' -> (b' -> b')))

which is also equal to: 也等于:

(a -> a' -> b' -> b')

for the same associativity rule. 对于相同的关联性规则。


Why after applying the composition functor you can use partial application? 为什么在应用成分函子后可以使用部分应用程序? Is there a rule for that? 有规则吗?

Partial application can be always applied when you have a function taking more than 1 "argument" (or more correctly, when you have a function that returns a function). 当您的函数接受多个“参数”时(或者更正确地说,当您有返回函数的函数时),总是可以应用部分应用程序。

In type signature, (->) is right associative, which implies that 在类型签名中, (->)是右关联的,这意味着

a -> b -> c

which is the type of a function that takes an argument of type a and return another function of type b -> c , equals 其是采用类型的参数的函数的类型a ,并返回类型的另一功能b -> c ,等于

a -> (b -> c)

However, it does not equals 但是,它不等于

(a -> b) -> c

which is the type of a function that takes another function of type a -> b as its only argument and return a value of type c . 这是一个函数的类型,该函数将a- a -> b类型a -> b另一个函数作为唯一参数,并返回c类型的值。

Question 1: 问题1:

How do i know which to take? 我怎么知道要服用哪一种?

You should choose first version, as you already did, because 您应该像以前一样选择第一个版本,因为

(a'->b'->b')->b'->[a']->b'

equals 等于

(a'->b'->b')->(b'->[a']->b')

And this is called currying , not greedy. 这就是所谓的currying ,而不是贪婪。

Question 2: 问题2:

Why can i remove them when you cannot remove those in the original foldr 当您无法删除原始文件夹中的内容时,为什么要删除它们

The same reason. 相同的原因。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM