Search code examples
haskellsyntaxstate-machinealgebraic-data-types

Local data type definitions


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.


Solution

  • 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.