所以,我正在尝试开发一个需要多态函数的函数。
我首先创建一个类Foo
,以表示example
函数中的约束类型参数。
module Test
where
class Foo a
此示例的随机类型......
newtype Bar = Bar Int
为了将Bar
传递给任何具有Foo
约束的东西,它需要有一个类型类,所以我这样做:
instance fooBar :: Foo Bar
一切都应该是完美的,但是,这不起作用,psc不认为类型统一,我不知道为什么:
example :: forall a. (Foo a) => (a -> Int) -> Int
example a = a (Bar 42)
错误如下:
Error found:
in module Test
at /Users/arahael/dev/foreign/test.purs line 11, column 16 - line 11, column 22
Could not match type
Bar
with type
a0
while checking that type Bar
is at least as general as type a0
while checking that expression Bar 42
has type a0
in value declaration example
where a0 is a rigid type variable
bound at line 11, column 1 - line 11, column 22
See https://github.com/purescript/documentation/blob/master/errors/TypesDoNotUnify.md for more information,
or to contribute content related to this error.
答案 0 :(得分:0)
比较
(1) example :: (forall a. (Foo a) => a -> Int) -> Int
与
(2) example :: forall a. (Foo a) => (a -> Int) -> Int
后者基本上对你(调用者)负责,以example
作为参数提供一个函数(你的选择!)w /签名a -> Int
(这样就有{{1} Foo
)的实例。
另一方面,前者说,你,来电者,实际上并没有选择这个函数a
。相反,正如Norman Ramsey在Haskell相关的stackoverflow回答here中解释的那样,当a -> Int
是"在左边"箭头(而不是"在箭头&#34之上;)实现决定提供什么功能。 forall
中的签名表示任何函数(2)
都将作为a -> Int
的参数(只要example
有Foo
个。{ / p>
a
只是"神奇地"然后,它起作用,因为编译器选择解包newtype (1)
的函数是完全令人满意的,并且在Bar
的情况下作为参数传递给example
。毕竟,(1)
的签名表明(1)
应该返回相同的example
值,无论给出Int
函数(只要有a -> Int
Foo
} a
的实例。在(2)
的情况下,Int
返回的example
值可能会因所提供的特定函数a -> Int
而异。编译器无法抓取任何它知道的随机满足类型的函数。它无法猜出调用者实际想到的a
或a -> Int
的类型。