never executed always true always false
1 {-# LANGUAGE ConstraintKinds #-}
2 {-# LANGUAGE FunctionalDependencies #-}
3 {-# LANGUAGE GADTs #-}
4 {-# LANGUAGE OverloadedStrings #-}
5 {-# LANGUAGE TypeFamilies #-}
6
7 {- |
8 Module : NITTA.Intermediate.Variable
9 Description : Types for variable representation
10 Copyright : (c) Aleksandr Penskoi, 2021
11 License : BSD3
12 Maintainer : aleksandr.penskoi@gmail.com
13 Stability : experimental
14 -}
15 module NITTA.Intermediate.Variable (
16 Var,
17 Variables (..),
18 Suffix (..),
19 ) where
20
21 import Data.Hashable
22 import Data.List (stripPrefix)
23 import Data.Set qualified as S
24 import Data.String
25 import Data.String.ToString
26 import Data.Text qualified as T
27 import Data.Typeable
28
29 -- | Variable identifier. Used for simplify type description.
30 type Var v = (Typeable v, Ord v, IsString v, ToString v, Suffix v, Hashable v)
31
32 -- | Type class of something, which is related to variables.
33 class Variables a v | a -> v where
34 -- | Get all related variables.
35 variables :: a -> S.Set v
36
37 -- | The type class for variable identifier modifications.
38 class Suffix v where
39 -- | Make a buffered version of the variable. For example: @"v" -> "v@buf"@
40 bufferSuffix :: v -> v
41
42 -- | Buffer sequence length of a variable (@"v" -> 0; "v@buf" -> 1; "b@buf@buf" -> 2@)
43 countSuffix :: v -> Int
44
45 -- FIXME: unsafe, because can create duplicate variable. Solution options:
46 --
47 -- - unsafeIO and counter;
48 -- - restriction on user's variable names + checking collision for each variable generation.
49 instance Suffix String where
50 bufferSuffix s = s ++ "@buf"
51 countSuffix [] = 0
52 countSuffix s
53 | Just s' <- stripPrefix "@buf" s = 1 + countSuffix s'
54 | otherwise = countSuffix $ drop 1 s
55
56 instance Suffix T.Text where
57 bufferSuffix s = s <> "@buf"
58 countSuffix s | s == T.empty = 0
59 countSuffix s
60 | Just s' <- T.stripPrefix "@buf" s = 1 + countSuffix s'
61 | otherwise = countSuffix $ T.drop 1 s