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?
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.
Functions aren't actually any different from any other type of data in Haskell, until you evaluate them – at which point there isn't any difference between a globally defined function, a function variable obtained by pattern matching, or an unnamed lambda.
In this case, as Will Ness said, it's easiest to obtain the function by pattern matching on a name,
advance (start, delta, terminate) = result
then you can, in this scope, use delta
and terminate
like any other function:
where result = delta start 'b' -- or whatever, conditional on terminate...