Function 在Haskell中展开函数

Function 在Haskell中展开函数,function,haskell,recursion,Function,Haskell,Recursion,在我的家庭作业中,我们得到了一个正则表达式。我必须返回一个电子NFA。我正在尝试构建delta函数。到目前为止,我已经: module ConsENFA where import Data.Set (Set, fromList, singleton, empty) import RegEx import ENFA epsilon :: RegExp Char epsilon = Symbol 'e' deltaTest :: RegExp Char -> Int -> (Int

在我的家庭作业中,我们得到了一个正则表达式。我必须返回一个电子NFA。我正在尝试构建delta函数。到目前为止,我已经:

module ConsENFA where

import Data.Set (Set, fromList, singleton, empty)
import RegEx
import ENFA

epsilon :: RegExp Char
epsilon = Symbol 'e'

deltaTest :: RegExp Char -> Int -> (Int -> Char -> Set Int)
deltaTest (Symbol sym) start = delta
    where
        delta :: Int -> Char -> Set Int
        delta start sym = singleton (start + 1)

deltaTest (Star re) start = delta
    where
        delta :: Int -> Char -> Set Int
        delta = deltaTest re (start + 1)
        delta start epsilon = fromList[1, 3]
我弄错了

ConsENFA.hs:19:9: error:
Conflicting definitions for `delta'
Bound at: ConsENFA.hs:19:9-13
          ConsENFA.hs:20:9-13
我假设这意味着我不能像那样扩展模式匹配,我不能添加更多的状态


我首先为单个标签定义增量,然后向先前定义的增量添加更多定义,但它不起作用。正确的方法是什么?

函数的所有定义必须具有相同的算术性,即相同数量的函数参数。您可以在三行中定义增量:

第一行是类型签名。 第二行是算术为零的delta的定义,在= 第三行是delta的另一个定义,它的左边有两个参数= 这两个定义具有不同的arity,因此编译器告诉您存在冲突的定义


扪心自问:达美航空公司的不良行为是什么?编译器将按照定义的顺序查看delta的定义,并选择模式匹配成功的第一个。由于第一个定义中没有参数,因此没有要匹配的模式,因此它将始终成功,并且永远不会调用第二个定义。

函数的所有定义都必须具有相同的arity,即相同数量的函数参数。您可以在三行中定义增量:

第一行是类型签名。 第二行是算术为零的delta的定义,在= 第三行是delta的另一个定义,它的左边有两个参数= 这两个定义具有不同的arity,因此编译器告诉您存在冲突的定义


扪心自问:达美航空公司的不良行为是什么?编译器将按照定义的顺序查看delta的定义,并选择模式匹配成功的第一个。由于第一个定义中没有参数,因此没有要匹配的模式,因此它将始终成功,并且永远不会调用第二个定义。

实际错误是因为delta被定义为一个函数,在deltaTest的第二个等式中,它的算术数为0,算术数为2。还不清楚实际的定义应该是什么。另一个未报告的错误是试图将epsilon的值用作模式匹配的一部分。@chepner使用epsilon不应引发错误;这只是名字的阴影。这可能是无意的,但不是编译错误。很快就发现了另一个拥有该文件的人。@crockeea我会假装这就是我所说的未报告:@crockeea抱歉,我在搜索中尝试了许多关键字,但找不到答案,因为我不知道正确的术语。实际错误是因为delta被定义为deltaTest的第二个等式中的一个函数,其中的arity 0和arity 2。还不清楚实际的定义应该是什么。另一个未报告的错误是试图将epsilon的值用作模式匹配的一部分。@chepner使用epsilon不应引发错误;这只是名字的阴影。这可能是无意中发生的,但不是编译错误。一个快速出现的错误是另一个有此错误的人。@crockeea我会假装这就是我所说的未报告的意思:@crockeea抱歉,我在搜索中尝试了许多关键字,但找不到答案,因为我不知道正确的术语。谢谢,这让它点击了。在特定事件发生后,执行delta x y=deltaTest重新启动+1 x y使其正常工作case@lombardo2很好,这解决了算术问题,但是第一个定义现在是完全通用的,第二个定义仍然不会被调用!编译时,您应该会收到一条关于模式匹配冗余的警告。这不会做你想做的。是的,刚刚注意到。我觉得艰难的开始和之前的开始是一样的,一个常数,但我猜不是。在对命令式进行了大量思考之后,很难掌握函数式编程。在这种情况下,它与命令式无关。你只需要习惯范围规则。模式中出现的标识符总是一个新的标识符,并且将在其作用域中阴影化任何具有相同名称的其他标识符。现在,下一步要学习的是了解模式发生的位置您可以使用防护装置,即delta x y | x==start,y==epsilon=..…谢谢,这使它点击。在特定事件发生后,执行delta x y=deltaTest重新启动+1 x y使其正常工作case@lombardo2很好,这解决了算术问题,但是第一个定义现在是完全通用的,第二个定义仍然不会被调用!编译时,您应该会收到一条关于模式匹配冗余的警告。这不会做你想做的。是的,刚刚注意到。我觉得艰难的开始和之前的开始是一样的,一个常数,但我猜不是。在对命令式进行了大量思考之后,很难掌握函数式编程。在这种情况下,它与命令式无关。你只需要习惯范围规则。pa中出现的标识符 ttern始终是一个新的名称,它将在其范围内隐藏任何具有相同名称的其他名称。现在,下一步要学习的是了解模式发生的位置您可以使用保护,即delta x y | x==start,y==epsilon=。。。。。