简体   繁体   中英

Purescript: Could not match type

In the REPL this works:

> mm n = (\n -> n * 2) <$> n
> mm (2:3:Nil)
(4 : 6 : Nil)

in a file this compiles and I can run it:

squareOf ls =
  map (\n -> n * n)  ls

however when I add a type definition to that function

squareOf :: List Int -> Int
squareOf ls =
  map (\n -> n * n)  ls

I get an error:

 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

I tried changing the signature to a type alias of the list, and also I tried a forall definition with no luck. If I inspect the definition created when I don't put signatures in my function I get:

forall t2 t3. Functor t2 => Semiring t3 => t2 t3 -> t2 t3

Can anyone explain why my signature is incorrect and also why am I getting this signature for the function?

Cheers

Edit: Thanks for the comments, updating the fn definition so it returns a List Int as well, and , of course it solves the problem

Assuming you're repl function is the behaviour you're after, you've missed out the map operator ( <$> ) in your later definitions.

Your repl function (with variables renamed for clarity) has the type:

mm :: forall f. Functor f => f Int -> f Int
mm ns = (\n -> n * 2) <$> ns

Which is to say: mm maps "times two" to something that is mappable" (ie a Functor)

Aside: you could be more concise/clear in your definition here:

mm :: forall f. Functor f => f Int -> f Int
mm = map (_*2)

This is similar to your squareOf definition, only now you're squaring so your use of (*) is more general:

squareOf :: forall f. Functor f => Semiring n => f n -> f n
squareOf = map \n -> n * n

Because (*) is a member of the Semiring typeclass.

But the signature you gave it suggests you're after some kind of fold ? Let me know what output you expect from your squareOf function and I'll update the answer accordingly.

Here is map :

class Functor f where
  map :: forall a b. (a -> b) -> f a -> f b

Narrowing to List Int and Int -> Int , the compiler infers

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

So, in squareOf , the expression reduces to a list of integers, not an integer. That is why the compiler complains.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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