I'm learning Haskell and working on a 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
When I run it, distance "" ""
gives the error:
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
I used guards instead of pattern matching for the main stuff, so it looks like it's that last where statement is the only place where pattern matching occurs, and must be what is causing the error. I see that it doesn't match against the Nothing
output.
However, I don't see how it could ever produce Nothing
, since things get evaluated lazily, I thought. In the case where the original strings are of different lengths, Nothing
will be returned immediately and distance
will never be called recursively, right?