[Haskell-beginners] How would I increment or otherwise change a value in a record with “Simon-ness”
Michael Litchard
michael at schmong.org
Wed Aug 5 21:22:59 UTC 2015
The below code is from this tutorial http://dev.stephendiehl.com/hask/
it illustrates very well how to operate on values from records with
"Simon-ness" (illustrated below). What I am struggling with is how to
modify values inside records with "Simon-ness", say incrementing "age". I
keep thinking it has to do with the way Label is defined with the
constructor Get. Could I add another constructor Put?
{-# LANGUAGE DataKinds #-}{-# LANGUAGE KindSignatures #-}{-# LANGUAGE
MultiParamTypeClasses #-}{-# LANGUAGE FunctionalDependencies #-}{-#
LANGUAGE FlexibleInstances #-}{-# LANGUAGE FlexibleContexts #-}{-#
LANGUAGE StandaloneDeriving #-}{-# LANGUAGE ExistentialQuantification
#-}{-# LANGUAGE ConstraintKinds #-}
import GHC.TypeLits
newtype Field (n :: Symbol) v = Field { unField :: v } deriving Show
data Person1 = Person1
{ _age :: Field "age" Int
, _name :: Field "name" String
}
data Person2 = Person2
{ _age' :: Field "age" Int
, _name' :: Field "name" String
, _lib' :: Field "lib" String
}
deriving instance Show Person1deriving instance Show Person2
data Label (l :: Symbol) = Get
class Has a l b | a l -> b where
from :: a -> Label l -> b
instance Has Person1 "age" Int where
from (Person1 a _) _ = unField a
instance Has Person1 "name" String where
from (Person1 _ a) _ = unField a
instance Has Person2 "age" Int where
from (Person2 a _ _) _ = unField a
instance Has Person2 "name" String where
from (Person2 _ a _) _ = unField a
age :: Has a "age" b => a -> b
age pnt = from pnt (Get :: Label "age")
name :: Has a "name" b => a -> b
name pnt = from pnt (Get :: Label "name")
-- Parameterized constraint kind for "Simon-ness" of a record.type
Simon a = (Has a "name" String, Has a "age" Int)
spj :: Person1
spj = Person1 (Field 56) (Field "Simon Peyton Jones")
smarlow :: Person2
smarlow = Person2 (Field 38) (Field "Simon Marlow") (Field "rts")
catNames :: (Simon a, Simon b) => a -> b -> String
catNames a b = name a ++ name b
addAges :: (Simon a, Simon b) => a -> b -> Int
addAges a b = age a + age b
names :: String
names = name smarlow ++ "," ++ name spj-- "Simon Marlow,Simon Peyton Jones"
ages :: Int
ages = age spj + age smarlow-- 94
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/beginners/attachments/20150805/b97774b5/attachment.html>
More information about the Beginners
mailing list