Read the paper "Data types a la carte"[1], and check out the compdata[2] library for an implementation. The idea is that instead of making a big union type like: data Answers = SexAnswer | AgeAnswer | etc... you make data Sex = M | F | etc newtype Age = Age Int and then you construct functions that accept sum types: ageOrSex :: Age :+: Sex -> m Bool ... A single type class, called :<: in the paper, handles dispatching from sums the underlying values to sums. [1]: http://www.cs.ru.nl/~W.Swierstra/Publications/DataTypesALaCarte.pdf [2: https://hackage.haskell.org/package/compdata On Fri, May 15, 2015 at 5:39 AM, Cody Goodman <codygman.consulting@gmail.com
wrote:
Tom, I'm trying to make a well-typed API to Question/Answers on medical forms. The questions will be lined with a specific code, so I want to enforce that certain codes can only contain certain types of answers.
Andras, thanks. I'll give that a try later today and let you know how it works.
On Fri, May 15, 2015 at 4:12 AM, Andras Slemmer <0slemi0@gmail.com> wrote:
You can do this, although you still need a datastructure that allows you to use the contained type:
{-# LANGUAGE GADTs #-} {-# LANGUAGE StandaloneDeriving #-} {-# LANGUAGE TypeSynonymInstances #-} module Tutorial where
data Gender = Male | Female deriving (Show)
data Race = White | Black deriving (Show)
type Age = Int
data Answer a where Answer :: RacistAgistSexist a => a -> Answer a
deriving instance Show w => Show (Answer w)
data GenderRaceAge = Gender Gender | Race Race | Age Age
class RacistAgistSexist a where genderRaceAge :: a -> GenderRaceAge instance RacistAgistSexist Gender where genderRaceAge = Gender instance RacistAgistSexist Race where genderRaceAge = Race instance RacistAgistSexist Age where genderRaceAge = Age
-- You can use genderRaceAge to get a GenderRaceAge out of the contained type if you don't know 'a'
On 15 May 2015 at 08:51, Tom Ellis <tom-lists-haskell-cafe-2013@jaguarpaw.co.uk> wrote:
On Fri, May 15, 2015 at 01:47:49AM -0500, Cody Goodman wrote:
How can I create Answers of type Gender, Race, or Age?
These should be possible:
λ> Answer Male λ> Answer White λ> Answer Black λ> Answer 28
Others such as using a string should not be possible:
λ> Answer "a string" -- should throw type error
It would probably help if you tell us why precisely you want this, and
in
particular why
data Answer = AnswerGender Gender | AnswerRace Race | AnswerAge Int
is not satisfactory.
Tom
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe