2

Problem:

Let's imagine we have a Passenger with start and end points represented by:

data Passenger a = Passenger { start :: a
                               , end :: a
                             }

Question:

How can I apply a class constraints to Passenger, where the start point shouldn't be equal to the end point?

P.S.: I have asked a similar question in the Scala community, but I didn't receive any answer. Considering that refined library for scala is inspired by refined for Haskell, also hearing about liquid-Haskell, I wonder how can resolve it using Haskell?

mkUltra
  • 2,828
  • 1
  • 22
  • 47
  • 6
    You cannot do this via types alone in standard Haskell – that would require dependent types. Use a [smart constructor](https://wiki.haskell.org/Smart_constructors) instead, or use liquid Haskell – AJF Dec 28 '18 at 17:18

1 Answers1

2

I just saw this. You can do so by specifying a refinement on the end field, e.g.:

{-@ data Passenger a = Passenger 
      { start :: a
      , end   :: {v:a | v /= start} 
      } 
  @-}

data Passenger a = Passenger 
  { start :: a
  , end   :: a
  }                        

ok :: Passenger String 
ok = Passenger "Alice" "Jones"

bad :: Passenger String
bad = Passenger "Bora" "Bora"

You can play with this online here:

http://goto.ucsd.edu:8090/index.html#?demo=permalink%2F1551137259_16583.hs

Ranjit Jhala
  • 1,242
  • 8
  • 18