How Can I call a function, that is integrated in a

2019-07-21 19:59发布

问题:

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?

回答1:

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.



回答2:

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