File: Tree.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 (76 lines) | stat: -rw-r--r-- 2,445 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
{-# LANGUAGE DataKinds           #-}
{-# LANGUAGE DeriveGeneric       #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications    #-}

{-
Example adapted from SYB
========================
-}

module Main (main) where

import Control.Lens
import Control.Monad (void)
import Data.Generics.Product
import GHC.Generics
import Test.HUnit

main :: IO ()
main = void $ runTestTT tests

-- A parameterised datatype for binary trees with data at the leafs
data Tree a w = Leaf a
              | Fork (Tree a w) (Tree a w)
              | WithWeight (Tree a w) w
       deriving (Show, Generic, Eq)

-- A typical tree
mytree :: Tree Int Int
mytree = Fork (WithWeight (Leaf 42) 1)
              (WithWeight (Fork (Leaf 88) (Leaf 37)) 2)

mytreeShown :: Tree String Int
mytreeShown = Fork (WithWeight (Leaf "42") 1)
                (WithWeight (Fork (Leaf "88") (Leaf "37")) 2)

-- A polymorphic-recursive structure
data Poly a b
  = PNil
  | PCons a (Poly b a)
  deriving (Show, Generic)

poly :: Poly Int String
poly = PCons 10 (PCons "hello" (PCons 20 (PCons "world" PNil)))

-- Print everything like an Int in mytree
-- In fact, we show two attempts:
--   1. print really just everything like an Int
--   2. print everything wrapped with Leaf
-- So (1.) confuses leafs and weights whereas (2.) does not.
tests :: Test
tests = TestList
  [ toListOf (types @Int) mytree ~=? [42,1,88,37,2]
  , toListOf (param @1) mytree       ~=? [42,88,37]

  -- Things not (easily) doable in SYB:
  -- change type of Tree by mapping a function over the second (from the right) param
  , (mytree & param @1 %~ show)                           ~=? mytreeShown
  -- collect values in poly corresponding to the first param
  , toListOf (param @0) poly                              ~=? ["hello", "world"]
  -- collect all Ints inside poly
  , toListOf (types @Int) poly                        ~=? [10, 20]
  -- map length over the Strings, then collect all Ints
  , toListOf (types @Int) (poly & param @0 %~ length) ~=? [10, 5, 20, 5]
  -- map length over the Strings, then collect all the resulting Ints
  , toListOf (param @0) (poly & param @0 %~ length)       ~=? [5,5]
  ]

-- original code from SYB:
--tests = show ( listify (\(_::Int) -> True)         mytree
--             , everything (++) ([] `mkQ` fromLeaf) mytree
--             ) ~=? output
--  where
--    fromLeaf :: Tree Int Int -> [Int]
--    fromLeaf (Leaf x) = [x]
--    fromLeaf _        = []