2

我是学生,在我的编程课程中,我们必须学习 Haskell。所以我是新手,我没有那么多经验。另外我不熟悉在论坛上发布问题。

所以首先我会发布图书馆,我必须与之合作。(DA:确定性自动机)

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)  

toDA 函数在其列表表示中采用自动机并将其转换为自动机。此功能和图书馆的其余部分由讲座主席提供。

现在的问题是写一个类型的函数

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

该函数接受一个自动机、一个状态和一个字符串,并在读取字符串后返回自动机的状态。

到目前为止,这个想法很清楚。DA 型自动机有一个状态转移函数增量。所以函数“advance”必须以某种方式调用那个 delta 函数。但是我怎样才能访问一个集成在一个类型中的函数呢?

4

2 回答 2

4

您为此使用模式匹配:

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

type关键字只是引入了类型同义词DA只是三元组的同义词(Integer, Integer -> Char -> Integer, Integer -> Bool)

你的命名令人困惑。deltaa自动机的定义中是一个状态转移函数,但是在toDA函数的定义中,一个名为的参数delta是一个列表。ListDAtype 也只是三元组的同义词(不同的一个 - 状态、转换列表和可接受状态列表)。

以下是如何使用递归 for 循环对其进行编码:

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

注意我们这里不需要startoraccept变量,所以我们可以在那里使用匿名变量模式_。此外,step是一个 type 的函数State -> Char -> State,它决定了函数调用中使用的参数的顺序。即它接受一个状态和一个字符,并产生一个新的状态。

如果您根本不了解 Haskell,您可能会从阅读(并完成)一个好的教程中受益,比如这个

最后,既然您说您“不熟悉在论坛上发布问题”,请阅读关于接受答案和一般常见问题解答

于 2012-11-20T11:55:07.957 回答
3

函数实际上与 Haskell 中的任何其他类型的数据没有任何不同,直到您评估它们——此时全局定义的函数、通过模式匹配获得的函数变量或未命名的 lambda 之间没有任何区别。

在这种情况下,正如 Will Ness 所说,通过对名称进行模式匹配来获取函数是最简单的,

advance (start, delta, terminate) = result

那么您可以在此范围内使用deltaterminate像任何其他功能一样:

 where result = delta start 'b'  -- or whatever, conditional on terminate...
于 2012-11-20T12:04:38.670 回答