File: Examples.hs

package info (click to toggle)
haskell-generic-lens 2.2.2.0-2
  • links: PTS
  • area: main
  • in suites: sid, trixie
  • size: 228 kB
  • sloc: haskell: 1,378; makefile: 6
file content (131 lines) | stat: -rw-r--r-- 3,571 bytes parent folder | download | duplicates (3)
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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
{-# LANGUAGE AllowAmbiguousTypes          #-}
{-# LANGUAGE DataKinds                    #-}
{-# LANGUAGE DeriveGeneric                #-}
{-# LANGUAGE DuplicateRecordFields        #-}
{-# LANGUAGE FlexibleContexts             #-}
{-# LANGUAGE GADTs                        #-}
{-# LANGUAGE NoMonomorphismRestriction    #-}
{-# LANGUAGE OverloadedLabels             #-}
{-# LANGUAGE PartialTypeSignatures        #-}
{-# LANGUAGE Rank2Types                   #-}
{-# LANGUAGE ScopedTypeVariables          #-}
{-# LANGUAGE TypeApplications             #-}
{-# LANGUAGE UndecidableInstances         #-}
{-# OPTIONS_GHC -Wno-missing-signatures   #-}
{-# OPTIONS_GHC -fno-warn-unused-imports  #-}

module Examples where

import Data.Function ((&))
import Data.Generics.Internal.VL.Lens
import Data.Generics.Product
import Data.Generics.Sum
import GHC.Generics
import Data.Generics.Labels
import Data.Generics.Internal.VL.Iso
import Data.Generics.Internal.VL.Prism
import Data.Generics.Internal.Profunctor.Lens
import Data.Generics.Internal.Profunctor.Iso
import Data.Generics.Internal.Profunctor.Prism

data Animal = Animal
  { name :: String
  , age  :: Int
  , eats :: String
  } deriving (Show, Generic)

data Human = Human
  { name    :: String
  , age     :: Int
  , address :: String
  , eats    :: String
  } deriving (Show, Generic)

data Living
  = Animal' { name :: String, eats :: String, age :: Int }
  | Human'  { name :: String, age :: Int, address :: String, eats :: String }
  deriving (Show, Generic)

toby :: Human
toby = Human { name = "Toby", age = 10, address = "London", eats = "Bread" }

growUp :: Animal -> Animal
growUp (Animal n a _) = Animal n (a + 10) "raw meat"

data MyRecord = MyRecord { field1 :: Int, field2 :: String } deriving Generic

--g :: Subtype s MyRecord => s -> String
--g s = s ^. super @MyRecord . label @"field2"

data Test a b = Test { fieldInt :: Int, fieldA :: a, fieldB :: b } deriving (Generic, Show)

-- | changedA :: Test Int String
-- >>> changedA
-- Test {fieldInt = 10, fieldA = 10, fieldB = "world"}
changedA = Test 10 "hello" "world" & field @"fieldA" .~ (10 :: Int)

-- | changedB :: Test String Int
-- >>> changedB
-- Test {fieldInt = 10, fieldA = "hello", fieldB = 10}
changedB = (Test 10 "hello" "world") & field @"fieldB" .~ (10 :: Int)

data Animal2 a
  = Dog (Dog a)
  | Cat Name Age
  | Duck Age
  deriving (Generic, Show)

data Dog a
  = MkDog
  { name   :: Name
  , age    :: Age
  , fieldA :: a
  }
  deriving (Generic, Show)
type Name = String
type Age  = Int
dog :: Animal2 Int
dog = Dog (MkDog "Shep" 3 30)

-- TODO: the error message for this case is ugly
-- data Dog a
--   = MkDog
--   { name    :: Name
--   , age     :: Age
--   , fieldA  :: a
--   , fieldA' :: a
--   }
--   deriving (Generic, Show)

-- |
-- >>> :t dog'
-- dog' :: Animal2 [Char]
dog' = dog & _Ctor @"Dog" . field @"fieldA" .~ "now it's a String"

stuff ::
  ( HasPosition 15 s t a String
  , HasField "test" s' t' a' b'
  , HasField "bar" a' b' s t
  ) => s' -> t'
stuff r = r & field @"test" . field @"bar" . position @15 .~ "hello"

stuff' ::
  ( HasPosition 15 s t a String
  , HasField "test" s' t' a' b'
  , HasField "bar" a' b' s t
  ) => s' -> t'
stuff' r = r & #test . #bar . position @15 .~ "hello"

data Foo m s = Foo
  { foo1 :: m s
  , foo2 :: [s]
  } deriving Generic

modifyFoo2 :: Foo (Either String) Int -> Foo Maybe Int
modifyFoo2 x = x & field @"foo1" .~ pure (1 :: Int)

data Bar a b = Bar
  { barField :: (a, b)
  } deriving Generic

modifiedBar = (Bar ("hello", "world")) & field @"barField" .~ ('c', 1 :: Int)