File: Set.hs

package info (click to toggle)
haskell-derive 2.5.16-1
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 460 kB
  • sloc: haskell: 3,686; makefile: 5
file content (40 lines) | stat: -rw-r--r-- 1,159 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
{-|
    A pseudo derivation.  For each field in the data type, deriving
    @Set@ generates @set@/FieldName/@ v x = x{@/fieldName/@ = v}@.
    This derivation is intended to work around the fact that in Haskell
    assigning to a field is not a first class object (although
    extracting from a field is).
-}
module Data.Derive.Set(makeSet) where

{-

test :: Computer

setSpeed :: Int -> Computer -> Computer
setSpeed v x = x{speed=v}

setWeight :: Double -> Computer -> Computer
setWeight v x = x{weight=v}

test :: Sample

-}

import Language.Haskell
import Data.Derive.Internal.Derivation
import Data.Maybe


makeSet :: Derivation
makeSet = derivationCustom "Set" $ \(_,d) -> Right $ concatMap (makeSetField d) $ dataDeclFields d


makeSetField :: DataDecl -> String -> [Decl]
makeSetField d field = [TypeSig sl [name set] typ, bind set [pVar "v",pVar "x"] bod]
    where
        set = "set" ++ title field
        typ = typField `TyFun` (dataDeclType d `TyFun` dataDeclType d)
        typField = fromBangType $ fromJust $ lookup field $ concatMap ctorDeclFields $ dataDeclCtors d

        bod = RecUpdate (var "x") [FieldUpdate (qname field) (var "v")]