Haskell Hacking: a journal of Haskell programming

Haskell Hacking has moved => Go here.
2006-11-19

More QuickChecks

On #haskell, Tony Morris asked how he could improve the following function:
replaceAll :: Eq a => [a] -> [a] -> [a] -> [a]
replaceAll [] _ xs = xs
replaceAll _ [] xs = xs
replaceAll _ _ []  = []
replaceAll xs ys zs'@(z:zs) = if xs `isPrefixOf` zs' then ys ++ drop (length xs) zs' else z : replaceAll xs ys zs
A quick clean up to use guards instead, and add some lightweight automated testing followed:
import Data.List
import Text.Printf
import Test.QuickCheck

replaceAll :: Eq a => [a] -> [a] -> [a] -> [a]
replaceAll [] _ xs = xs
replaceAll _ [] xs = xs
replaceAll _ _ []  = []
replaceAll xs ys zs'@(z:zs)
    | xs `isPrefixOf` zs' = ys ++ drop (length xs) zs'
    | otherwise           = z : replaceAll xs ys zs

--
-- testsuite
--

prop_length xs ys zs =
    length xs == length ys ==>
        length (replaceAll xs ys zs) == length zs
    where _ = xs :: [Int]

run = mapM_ (\(s,a) -> printf "%-25s: " s >> a) [("length", test prop_length)]

{-

*Main> :l A.hs
*Main> run
length                   : OK, passed 100 tests.

-}
It's great how you can so quickly roll together nice resuable (higher order + polymorphic = reusable), and well specified code in Haskell.

/home :: /haskell :: permalink :: rss

About

Real World Haskell

RWH Book Cover

Archives

Recommended

Blog Roll

Syndicate