Alex Rivera | Logout

How to create Type which contains String with limited length in Haskell

Asked 2012-05-04T23:53:24.360
10

Possible Duplicate:
How to make a type with restrictions

Is it possible in Haskell to create a type for example "Name" which is a String but containing no more then 10 letters?

If not how can I forbid to create a Person with to long name (where Person is defined like that: data Person = Person Name).

Maybe it is not important at all, maybe that kind of problems should be solved in Haskell in a different way?

Edit
Report

1 Answer

9

dave4420 has the answer for what you should do. That is, only export smart constructors. In a dependently typed language you could limit data types to certain forms. But, Haskell is not dependently typed.

Wait, no that is not true. Haskell is "the worlds most popular dependently typed language". You just have to fake the dependent types. Stop. Read no further if you are 1. still learning basic Haskell 2. not totally insane.

It is possible to encode your "no longer than 10 characters" constraint in the type system. with a type like

data Name where
    Name :: LessThan10 len => DList Char len -> Name

but I'm getting ahead of myself

first of all, you need tons of extensions (I assume GHC 7.4, early versions can still do it, but it is much more of a pain)

{-# LANGUAGE TypeFamilies,
             DataKinds,
             GADTs,
             FlexibleInstances,
             FlexibleContexts,
             ConstraintKinds-}

import Prelude hiding (succ)

now we build some machinery for type level naturals...using the new DataKinds extension

data Nat = Z | S Nat

type N1 = S Z --makes writing numbers easier
type N2 = S N1
--etc
type N10 = S N9

now we need a data representation of numbers and a way to generate them

data Natural n where
    Zero :: Natural Z
    Succ :: Natural a -> Natural (S a)

class Reify a where
   reify :: a

instance Reify (Natural Z) where
   reify = Zero

instance Reify (Natural n) => Reify (Natural (S n)) where
   reify = Succ (reify)

okay, now we can encode the idea of number being less than 10, and write a helper to test it for boot

type family LTE (a :: Nat) (b :: Nat) :: Bool
type instance LTE Z b = True
type instance LTE (S a) Z = False
type instance LTE (S a) (S b) = LTE a b

--YAY constraint kinds!
type LessThan10 a = True ~ (LTE a N
answered 2012-05-05T06:19:55.130

Your Answer