我正在学习Haskell和Hamming distance exercise。
module Hamming (distance) where
distance :: String -> String -> Maybe Int
distance (x:xs) (y:ys)
| lengthX /= lengthY = Nothing
| lengthX == 0 = Just 0
| otherwise = Just (headDistance + tailDistance)
where
lengthX = length (x:xs)
lengthY = length (y:ys)
headDistance = if x /= y then 1 else 0
(Just tailDistance) = distance xs ys
当我运行它时,distance "" ""
给出错误:
haskell/hamming » stack test
hamming> test (suite: test)
distance
empty strands FAILED [1]
Failures:
src/Hamming.hs:4:1:
1) distance empty strands
uncaught exception: PatternMatchFail
src/Hamming.hs:(4,1)-(12,40): Non-exhaustive patterns in function distance
To rerun use: --match "/distance/empty strands/"
Randomized with seed 892503112
Finished in 0.0003 seconds
1 example, 1 failure
hamming> Test suite test failed
Test suite failure for package hamming-2.3.0.10
test: exited with: ExitFailure 1
Logs printed to console
我使用警卫而不是模式匹配的主要内容,所以它看起来像最后一个地方的语句是模式匹配发生的唯一地方,必须是导致错误的原因。我看到它与Nothing
输出不匹配。
然而,我不明白它是如何产生Nothing
的,因为事情是懒惰的评估,我想。在原始字符串长度不同的情况下,Nothing
将立即返回,distance
将永远不会被递归调用,对吗?
此错误与您的守卫无关-它比这更基本。
你有:
distance :: String -> String -> Maybe Int
distance (x:xs) (y:ys)
- - more code
,但没有其他情况。所以你确实有非详尽的模式,因为你所涵盖的唯一情况是当第一个参数匹配(x:xs)
,第二个(y:ys)
,所以它会崩溃,只要任何一个参数是空的-更不用说两个,因为你在这里调用它。