File: LazySet.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 (38 lines) | stat: -rw-r--r-- 1,316 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
{-|
    A pseudo derivation.  For each field in the data type, deriving
    @LazySet@ generates a function like a record updator, but lazy where possible.
    This is very useful in certain situations to improve laziness
    properties.  A setter is only lazy if that field is present in one constructor.
-}
module Data.Derive.LazySet(makeLazySet) where
{-

test :: Computer

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

setWeight :: Double -> Computer -> Computer
setWeight v x = Laptop v (speed x)

test :: Sample

-}

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


makeLazySet :: Derivation
makeLazySet = derivationCustom "LazySet" $ \(_,d) -> Right $ concatMap (makeLazySetField d) $ dataDeclFields d


makeLazySetField :: DataDecl -> String -> [Decl]
makeLazySetField d field = [TypeSig sl [name fun] typ, bind fun [pVar "v",pVar "x"] bod]
    where
        fun = "set" ++ title field
        typ = t `TyFun` (dataDeclType d `TyFun` dataDeclType d)
        (t,c):tc = [(fromBangType t,c) | c <- dataDeclCtors d, (n,t) <- ctorDeclFields c, n == field]

        bod | null tc = apps (con $ ctorDeclName c) [n == field ? var "v" $ Paren $ App (var n) (var "x") | (n,t) <- ctorDeclFields c]
            | otherwise = RecUpdate (var "x") [FieldUpdate (qname field) (var "v")]