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 IntInt -> Int,编译器推断

map :: (Int -> Int) -> List Int -> List Int

因此,在 squareOf 中,表达式简化为整数列表,而不是整数。这就是编译器抱怨的原因。