Search code examples
haskelltypestuplessml

Define types directly in tuple like SML?


I remember this from SML and The Little MLer

fun has_steak (_ : meza, Steak : main, _ : dessert) = true
| has_steak _ = false

In other words, the types of the 3-tuple are being established in-line, so to speak without an explicit type declaration. So if I have this in Haskell

data Meza = Shrimp | Calamari | Escargots | Hummus deriving (Show,Eq)
data Main = Steak | Ravioli | Chicken | Eggplant deriving (Show,Eq)
data Salad = Green | Cucumber | Greek deriving (Show,Eq)
data Dessert = Sundae | Mousse | Torte deriving (Show,Eq)

This

hasSteak :: (Meza,Main,Dessert) -> Bool
hasSteak (_,Steak,_) = True
hasSteak _ = False

works fine, but could I do something similar to the in-line SML above in Haskell? This doesn't work

hasSteak ((_::Meza),Steak,(_::Dessert)) = True
hasSteak _ = False

and this

hasSteak (_,Steak,_) :: (Meza,Main,Dessert) = True
hasSteak _ = False

doesn't fly either. It seems I've seen this sort of "in-line" type defining in another context, though.


Solution

  • You say this doesn't work:

    hasSteak ((_::Meza),Steak,(_::Dessert)) = True
    hasSteak _ = False
    

    But the error it gives says Type signatures are only allowed in patterns with ScopedTypeVariables. All you have to do is turn on the ScopedTypeVariables extension (with :set -XScopedTypeVariables at the GHCi prompt or {-# LANGUAGE ScopedTypeVariables #-} in a .hs file), and then it will work and do exactly what you want.