Emi*_*iga 4 haskell functional-programming
这是我的代码:
reverseEncode :: Char -> String -> Int -> Char
reverseEncode _ [] _ = ?
reverseEncode c (x:xs) offset
| alphaPos c == (alphaPos x + offset) `mod` 26 = chr (((alphaPos x + offset) + 65) `mod` 26)
| otherwise = reverseEncode c xs offset
Run Code Online (Sandbox Code Playgroud)
这只是虚拟Enigma Machine中使用的一种小方法。在编写没有第二行的函数并对其进行测试之后,我得到了以下异常:
Non-exhaustive patterns in function reverseEncode
Run Code Online (Sandbox Code Playgroud)
然后我意识到我没有告诉函数何时停止递归。这就是第二行代码的诞生方式。显然,我可以在每个步骤中检查字符串的长度,但是看起来并不优雅。
在Haskell中,有什么我可以代替的吗??如果没有,我有什么可以定义的吗?还是可以通过更好的方式完成此操作?
编辑:我实际上已经通过检查字符串的长度尝试了版本,并且我得到了相同的异常。那么我该如何运作呢?
没有空字符。但是,您可以使用Nul字符 [wiki]之类的字符。例如:
reverseEncode :: Char -> String -> Int -> Char
reverseEncode _ [] _ = '\00'
reverseEncode c (x:xs) offset
| alphaPos c == sm `mod` 26 = chr ((sm + 65) `mod` 26)
| otherwise = reverseEncode c xs offset
where sm = alphaPos x + offset
Run Code Online (Sandbox Code Playgroud)
但是,更Haskellish的方法是更改返回类型。例如,使用a Maybe Char
代替。这通常用于“可能失败的计算”。所以我们可以这样:
reverseEncode :: Char -> String -> Int -> Maybe Char
reverseEncode _ [] _ = Nothing
reverseEncode c (x:xs) offset
| alphaPos c == sm `mod` 26 = Just (chr ((sm + 65) `mod` 26))
| otherwise = reverseEncode c xs offset
where sm = alphaPos x + offset
Run Code Online (Sandbox Code Playgroud)
Nothing
因此,这里的表示我们不满足条件而到达列表的末尾,并且Just x
表示计算得出了答案x
。