Purescript:无法匹配类型
Purescript: Could not match type
在 REPL 中这有效:
> mm n = (\n -> n * 2) <$> n
> mm (2:3:Nil)
(4 : 6 : Nil)
在这个编译的文件中,我可以 运行 它:
squareOf ls =
map (\n -> n * n) ls
但是当我向该函数添加类型定义时
squareOf :: List Int -> Int
squareOf ls =
map (\n -> n * n) ls
我得到一个错误:
Could not match type
List Int
with type
Int
while checking that type t0 t1
is at least as general as type Int
while checking that expression (map (\n ->
(...) n
)
)
ls
has type Int
in value declaration squareOf
where t0 is an unknown type
t1 is an unknown type
我尝试将签名更改为列表的类型别名,并且尝试了 forall 定义,但没有成功。
如果我检查在我没有在我的函数中放置签名时创建的定义,我得到:
forall t2 t3. Functor t2 => Semiring t3 => t2 t3 -> t2 t3
谁能解释为什么我的签名不正确以及为什么我得到这个函数签名?
干杯
编辑:感谢您的评论,更新了 fn 定义,因此它 returns 和 List Int
一样,而且,当然它解决了问题
假设您的 repl 函数是您所追求的行为,那么您在以后的定义中遗漏了地图运算符 (<$>
)。
您的 repl 函数(为清楚起见重命名了变量)的类型为:
mm :: forall f. Functor f => f Int -> f Int
mm ns = (\n -> n * 2) <$> ns
也就是说:mm 将 "times two" 映射到可映射的对象(即 Functor)
旁白:您可以在此处定义更多 concise/clear:
mm :: forall f. Functor f => f Int -> f Int
mm = map (_*2)
这与您的 squareOf
定义类似,只是现在您 平方 所以您对 (*)
的使用更通用:
squareOf :: forall f. Functor f => Semiring n => f n -> f n
squareOf = map \n -> n * n
因为(*)
是Semiring类型类的成员。
但是你给它的签名表明你在追求某种 fold
?让我知道您希望从 squareOf
函数得到什么输出,我会相应地更新答案。
这里是map
:
class Functor f where
map :: forall a b. (a -> b) -> f a -> f b
缩小到 List Int
和 Int -> Int
,编译器推断
map :: (Int -> Int) -> List Int -> List Int
因此,在 squareOf
中,表达式简化为整数列表,而不是整数。这就是编译器抱怨的原因。
在 REPL 中这有效:
> mm n = (\n -> n * 2) <$> n
> mm (2:3:Nil)
(4 : 6 : Nil)
在这个编译的文件中,我可以 运行 它:
squareOf ls =
map (\n -> n * n) ls
但是当我向该函数添加类型定义时
squareOf :: List Int -> Int
squareOf ls =
map (\n -> n * n) ls
我得到一个错误:
Could not match type
List Int
with type
Int
while checking that type t0 t1
is at least as general as type Int
while checking that expression (map (\n ->
(...) n
)
)
ls
has type Int
in value declaration squareOf
where t0 is an unknown type
t1 is an unknown type
我尝试将签名更改为列表的类型别名,并且尝试了 forall 定义,但没有成功。 如果我检查在我没有在我的函数中放置签名时创建的定义,我得到:
forall t2 t3. Functor t2 => Semiring t3 => t2 t3 -> t2 t3
谁能解释为什么我的签名不正确以及为什么我得到这个函数签名?
干杯
编辑:感谢您的评论,更新了 fn 定义,因此它 returns 和 List Int
一样,而且,当然它解决了问题
假设您的 repl 函数是您所追求的行为,那么您在以后的定义中遗漏了地图运算符 (<$>
)。
您的 repl 函数(为清楚起见重命名了变量)的类型为:
mm :: forall f. Functor f => f Int -> f Int
mm ns = (\n -> n * 2) <$> ns
也就是说:mm 将 "times two" 映射到可映射的对象(即 Functor)
旁白:您可以在此处定义更多 concise/clear:
mm :: forall f. Functor f => f Int -> f Int
mm = map (_*2)
这与您的 squareOf
定义类似,只是现在您 平方 所以您对 (*)
的使用更通用:
squareOf :: forall f. Functor f => Semiring n => f n -> f n
squareOf = map \n -> n * n
因为(*)
是Semiring类型类的成员。
但是你给它的签名表明你在追求某种 fold
?让我知道您希望从 squareOf
函数得到什么输出,我会相应地更新答案。
这里是map
:
class Functor f where
map :: forall a b. (a -> b) -> f a -> f b
缩小到 List Int
和 Int -> Int
,编译器推断
map :: (Int -> Int) -> List Int -> List Int
因此,在 squareOf
中,表达式简化为整数列表,而不是整数。这就是编译器抱怨的原因。