3
votes

I am new to Purescript (as well as Haskell) and I am stuck with a cannot unify error. Initially I had:

newtype Domain = Domain String

newtype Keyword = Keyword String

type Result = {
        domain    :: Domain,
        occurred   :: Boolean,
        position  :: Number,
        quality   :: Number
    }

is_min_pos :: Maybe Result -> Maybe Result -> Maybe Result
is_min_pos Nothing Nothing = Nothing
is_min_pos Nothing y = y
is_min_pos x Nothing = x
is_min_pos x y = if y.position < x.position then y else x     

This was giving me the error

Cannot unify type
  Prim.Object
with type
  Data.Maybe.Maybe

I assumed it was because it was expecting x and y to be of type Maybe Record. So to be explicit I changed the code to, to pattern match by type.

data Result = Result {
        domain    :: Domain,
        occurred   :: Boolean,
        position  :: Number,
        quality   :: Number
    }

is_min_pos (Result x) (Result y) = if y.position < x.position then y else x

Now I get the error

Cannot unify type
  Data.Maybe.Maybe Processor.Result
with type
  Processor.Result

And this refers to this section

y.position < x.position -- in the first case

and in the second case

Result x -- on the pattern matching side

I am working on it further

type Results = List Result

get_item_with_min_position :: Results -> Maybe Result
--get_item_with_min_position [] = Nothing
get_item_with_min_position results = foldl is_min_pos Nothing results

I am using 'foldl' from Foldable. I am not sure how to pattern match an empty list. If I could, I would change the type signature to

is_min_pos :: Maybe Result -> Result -> Maybe Result

I now get the error

Cannot unify type
    Prim.Object
with type
    Data.Maybe.Maybe

It is understandable because in

foldl is_min_pos Nothing results

results is of type List Result is_min_pos expects Maybe Result

What would be a clean way to solve this?

1

1 Answers

5
votes

The Maybe type has two data constructors: Nothing, which you are correctly matching, and Just. If you want to match something of type Maybe a which does contain a value, you should match the Just constructor.

You need to modify the final case as follows:

is_min_pos (Just x) (Just y) = if y.position < x.position 
                                  then Just y 
                                  else Just x

Here, Just x has the type Maybe Result, which is correct according to the type signature, and so x has type Result, so you can use the .position accessor to read its position property.