Search code examples
haskelldeterministicautomaton

How Can I call a function, that is integrated in a type in Haskell?


I am student and in my programming course we have to learn Haskell. So I am new to it and i don't have that much experience. Also I am not familiar with posting questions in a forum.

So first of all I will post the library, I have to work with. (DA : Deterministic Automaton)

type State = Integer
type DA = (State, State -> Char -> State, State -> Bool)
type ListDA = (State, [((State, Char), State)], [State])

a :: DA
a = (0, delta, (==1))
  where
    delta 0 'a' = 1
    delta 1 'a' = 1
    delta 2 'a' = 1
    delta 0 'b' = 2
    delta 1 'b' = 2
    delta 2 'b' = 2

toDA :: ListDA -> DA
toDA (start, delta, final) = (start, deltaFun delta, (`elem` final))
  where deltaFun dl = curry (fromMaybe 0 . flip lookup dl)  

The toDA function takes an automaton in its list representation and converts it into an automaton. This function and the rest of the library is given by the chair of the lecture.

The problem is now to write a function of type

advance :: DA -> State -> String -> State

This function takes an automaton, a state and a String and returns the state of the automaton after reading the String.

The Idea is clear so far. An automaton of type DA has got a state-transition-function delta. So the function "advance" has to call that delta function in some way. But how can I access a function, that is integrated in a type?


Solution

  • You use pattern matching for that:

    advance :: DA -> State -> String -> State
    advance (start, step, accept) fromState chars = ....
    

    The type keyword just introduces type synonyms. DA is just a synonym for a triple (Integer, Integer -> Char -> Integer, Integer -> Bool).

    Your naming is confusing. delta in the definition of a automaton is a state transition function, but in the definition of toDA function, a parameter named delta is a list. ListDA type is also just a synonym for a triple (a different one - of a state, a list of transitions, and a list of acceptable states).

    Here is how this can be coded, using recursion for loops:

    advance (_, step, _) fromState chars = go fromState chars
      where
        go s []     = ...  -- stop, and produce the state as the answer,
                           -- when the input string (list of chars) has ended
        go s (c:cs) =         -- if not, then
          let s2 = step s c   -- make one step
          in  go .......      -- and loop with new values
    

    Notice we have no need here for the start or accept variables, so we can use the anonymous variable pattern _ there. Also, step is a function of type State -> Char -> State, and that dictates the order of arguments used in the function call there. I.e. it accepts a state and a character, and produces a new state.

    If you don't know Haskell at all, you will likely benefit from reading (and working through) a good tutorial, like this one.

    Lastly, since you've said you're "not familiar with posting questions in a forum", please read about accepting answers, and FAQ in general.