File: Ref.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 (42 lines) | stat: -rw-r--r-- 1,359 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
41
42
{-|
    A pseudo derivation.  For each field in the data type, deriving
    @Ref@ generates @ref@/FieldName/@ = Ref { select = @/fieldName/@ , update =
    \ f v -> v { @/fieldName/@ = f (@/fieldName/@ v) } }@.

    This is intended for use with the compositional functional references
    described in
    <http://www.haskell.org/pipermail/haskell-cafe/2007-June/026477.html>.
-}
module Data.Derive.Ref(makeRef) where

{-
test :: Sample

test :: Computer

refSpeed :: Ref Computer
refSpeed = Ref {select = speed, update = \f v -> v{speed = f (speed v)}}

refWeight :: Ref Computer
refWeight = Ref {select = weight, update = \f v -> v{weight = f (weight v)}}
-}

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


makeRef :: Derivation
makeRef = derivationCustom "Ref" $ \(_,d) -> Right $ concatMap (makeRefField d) $ dataDeclFields d


makeRefField :: DataDecl -> String -> [Decl]
makeRefField d field = [TypeSig sl [name ref] typ, bind ref [] bod]
    where
        ref = "ref" ++ title field
        typ = TyApp (tyCon "Ref") (dataDeclType d)

        bod = RecConstr (qname "Ref")
            [FieldUpdate (qname "select") (var field)
            ,FieldUpdate (qname "update") $ Lambda sl [pVar "f",pVar "v"] $
                RecUpdate (var "v") [FieldUpdate (qname field) $ App (var "f") $ Paren $ App (var field) (var "v")]
            ]