Implementing finite state automata in Haskell, I'd like to do this:
zigzag :: Int -> Int -> [Int]
zigzag low upp = fsa Incr low
where
data State = Incr | Decr
fsa :: State -> Int -> [Int]
fsa state n
= n : case state of
Incr | n < upp -> fsa Incr (n + 1)
| otherwise -> fsa Decr (n - 1)
Decr | n > low -> fsa Decr (n - 1)
| otherwise -> fsa Incr (n + 1)
But I can't:
error: parse error on input ‘data’
Is there a better way than to separate the State
definition from zigzag
?
I wouldn't want to encode state identifiers implicitly in terms of booleans or numbers if I can use an explicit enumeration or data type. Local function definition is meant to enable modularity, to protect the integrity of descriptive namespaces from single-relation/use clutter. I don't understand why data definitions in that respect should be treated differently.
You can't put data
definitions locally, only at the top level. However you could use a Bool
and if
rather than a custom data type and case
.
Alternatively, you can put the function and data type in their own module if you don't want to export the data
type.
It has been proposed to include this feature, but it isn't a priority for some reason. I guess generally people view types as high-level protocols between top-level functions, not typically between where
-level functions.