This sort of thing is (relatively) nicely solved by lenses with typeclasses, e.g.,

class HasName a where
  name :: Lens' a String

Then, with the appropriate lenses,

person ^. name
person & name .~ "Ben"
person1 ^. name
person1 & name .~ "Jerry"


On Wed, Aug 5, 2015 at 2:53 PM Michael Litchard <michael@schmong.org> wrote:
I noticed the mail got archived, but I have yet to see it in my mail queue. Is it just me? Or did something go wrong with distribution?

On Wed, Aug 5, 2015 at 2:24 PM, Sumit Sahrawat, Maths & Computing, IIT (BHU) <sumit.sahrawat.apm13@iitbhu.ac.in> wrote:
More suitable for the haskell-cafe. Routing.

On 6 August 2015 at 02:52, Michael Litchard <michael@schmong.org> wrote:

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 Person1
deriving 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

_______________________________________________
Beginners mailing list
Beginners@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners




--
Regards

Sumit Sahrawat

_______________________________________________
Beginners mailing list
Beginners@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners


_______________________________________________
Beginners mailing list
Beginners@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners