Reputation: 491
I'm a newbie at PureScript trying out some code at this link. I've pasted the code here:
module Main where
import Prelude
import Data.Foldable (fold)
import Data.Tuple
import Data.Map as Map
import Data.List
import Effect (Effect)
import Effect.Console (log)
import TryPureScript
data Item a = Left a
toplevelDecisions :: Map.Map (String) (Item String)
toplevelDecisions = Map.fromFoldable [ Tuple "Notify Individuals" (Left "omitted"), Tuple "Assessment" (Left "omitted") ]
getTheFirstInTuple :: (List -> Tuple) -> List
getTheFirstInTuple a = fst <<< unzip a
main = render =<< withConsole do
log $ getTheFirstInTuple toplevelDecisions
I encountered this error: Could not match kind Type -> Type with kind Type
. Does anyone know how to resolve this problem? What I'm trying to do is to convert a List of Tuples into a Tuple of 2 Lists, and then extracting just the first List.
Upvotes: 0
Views: 186
Reputation: 80734
When you write List
, you mean a list of what? A list of numbers, a list of strings, or of what? This has to be specified in the type. For example, a list of integer numbers would be List Int
, a list of strings would be List String
, and so on.
This is what the compiler means complaining about "kind Type -> Type". An argument is missing for the type List
. The syntax is borrowed from functions: if a function takes an Int
parameter and returns a String
result, we write its type as Int -> String
. Same works with types: if a type takes a Type
as parameter and the result of that is also Type
, we write its kind as Type -> Type
. Functions have types, and types have kinds. Same idea, just a on a different level.
Similarly with Tuple
: a tuple of what? It could be Tuple Int Int
or Tuple String Boolean
, but it can't be just Tuple
. Not enough information.
If you wanted, as you say, convert a list of tuples to a list of just those tuples' first elements, then the signature might be something like:
getTheFirstInTuple :: List (Tuple String Int) -> List String
Or, if you wanted your function to work not just for String
and Int
, but for all types, you can make it generic:
getTheFirstInTuple :: forall a b. List (Tuple a b) -> List a
Here a
and b
stand for some types, but your function doesn't care what they are exactly. It will work "for all possible a
and b
" - that's what the forall
keyword means.
But after you fix the type signature, I'm afraid your function won't work anyway, because its body doesn't make sense either. Honestly, to me it looks like you're trying to guess the right syntax without understanding what it means.
And the way you're calling your function getTheFirstInTuple toplevelDecisions
also won't work, because toplevelDecisions
is not a List
, but a Map
. Look: you wrote its type yourself.
Finally I'd like to note, just in case you didn't know, that in PureScript a construct with square brackets, like [1, 2, 3]
, is actually an Array
, not a List
Upvotes: 2
Reputation: 4649
The specific error you have here is from the type (List -> Tuple) -> List
- both the List
and Tuple
types take arguments indicating the type of values they carry.
The "kind" is "the type of a type", so Type -> Type
means it's a type that accepts one argument. Given that, it seems this specific error will be referring to the List
usage, as if it was complaining about the Tuple
, the kind would be Type -> Type -> Type
.
Omitting the type signature in this case would also work, the compiler will warn about any top level declarations that are missing type annotations, telling you what it inferred for them. This doesn't always work, when fancier type system features get involved, but for this function it would be absolutely fine.
However... there are further problems in the code after you fix that, I'm afraid to say basically none of it works just now! But hopefully that will set you in approximately the right direction, and you can ask further questions if you get stuck again.
You might want to try asking on the PureScript discord for a more interactive conversation in figuring it out.
Upvotes: 1