我需要创建一个接受字符串和解码规则的函数。它应该改变字符串中的字符,直到根据解码规则没有任何可能的改变。每次我得到字符串和解码规则(第一是什么改变,第二是什么)。
我很迷茫,我试着创建所有可能的组合,然后根据规则生成列表。下面是我的尝试。
rules = [('E',"GZ"),('F',"HK"),('C',"EF"),('J',"CC")]
string = "JCEJ"
combinations = [(x,y,z) | x <- [ch | ch <- string], y <- [x | (x,y) <- rules], z <- [y | (x,y) <- rules]]
generate = [z | (x,y,z) <- combinations, if x == y then z else x]
错误消息:
decoder.hs:8:57: error:
• Couldn't match expected type ‘Bool’ with actual type ‘[Char]’
• In the expression: z
In the expression: if x == y then z else x
In a stmt of a list comprehension: if x == y then z else x
|
8 | generate = [z | (x,y,z) <- combinations, if x == y then z else x]
| ^
decoder.hs:8:64: error:
• Couldn't match expected type ‘Bool’ with actual type ‘Char’
• In the expression: x
In the expression: if x == y then z else x
In a stmt of a list comprehension: if x == y then z else x
|
8 | generate = [z | (x,y,z) <- combinations, if x == y then z else x]
| ^
3条答案
按热度按时间bnl4lu3b1#
你有一个
rules
的查找表,Haskell有一个方便的lookup
函数:我们可以在字符串上折叠查找:
我们将其命名为
singlePassDecode
:但是,一次传递并不一定就能完成任务,我们需要递归调用它,直到没有转换需要执行为止,这意味着我们需要知道输入字符串中是否有字符在查找表中。
剩下的
...
由正确的递归调用填充,以避免给出完整的答案。第一个条件也可以表达如下。
kzmpq1sx2#
String
是Char
的列表,因此[ch | ch <- string]
不是必需的。这里我们用
x
定义了一些内部列表解析,但是x
是一个更具有局部作用域的变量,而不是x <- [ ch | ch <- str]
中的x
那样的x
。你可以让一个过滤条件来过滤,这样:
这里的
…
是您需要填写的部分。它需要将x
与x'
进行比较。wfauudbj3#
规则列表描述了从一个
Char
到两个Char
(如果有匹配)或一个Char
(如果没有匹配,则为原始输入)的Map。我们可以通过总是返回一个[Char]
来处理这两种情况,并且我们可以泛化到任何a
,而不是特定于Char
:由于这种Map不依赖于其他上下文,因此
concatMap
(也拼写为(>>=)
)是一个很好的工具,可以将其应用于输入列表并连接结果。如果有一个函数可以重复应用一个函数,直到它不产生任何变化,那么它也会很有用:
然后,剩下的就是将我们的工具组合在一起:
我们可以看到,它产生了你所期望的答案: