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
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)]
It's great how you can so quickly roll together nice resuable (
jcreigh wrote
on his RPN calculator in Haskell. Here's some refactoring for fun
(adding StateT and readline, mostly).
import Data.Char
import Data.Maybe
import System.Console.Readline
import System.Exit
import System.IO
import Control.Monad.State
import qualified Data.Map as M
type Stack = [Double]
type Operator = Stack -> Stack
forever a = a >> forever a
io = liftIO
main = runStateT (forever repl) []
repl = do
m <- io $ readline "> "
case m of
Nothing -> io $ exitWith ExitSuccess
Just l -> do modify $ flip eval (parse l)
io . print =<< get
eval = foldl (flip id)
parse = map parse' . words
parse' t | Just op <- M.lookup t table = op
| otherwise = (read t :)
table = M.fromList
[("+" , binaryOp (+) )
,("-" , binaryOp () )
,("*" , binaryOp (*) )
,("/" , binaryOp (/) )
,("**" , binaryOp (**) )
,("log" , unaryOp log )
,("sqrt" , unaryOp sqrt )
,("dup" , \(x:xs) -> x:x:xs )
,("swap" , \(a:b:xs) -> b:a:xs )
,("pop" , tail )]
unaryOp f (a:s) = f a : s
binaryOp f (a:b:s) = f b a : s
/home ::
/haskell ::
permalink ::
rss
Magnus wrote about
his beginning steps in Haskell. Here's a quick refactor of the code, for
fun, mostly:
import Data.Either
import MissingH.Time.ParseDate
import System.Environment
import System.Locale
import System.Time
diffAndToString s e = formatTimeDiff defaultTimeLocale "%R" diff
where diff = normalizeTimeDiff $ diffClockTimes (toClockTime s) (toClockTime e)
calcDiff start end = case (parse start, parse end) of
(Nothing, _) -> Left "start time"
(_, Nothing) -> Left "end time"
(Just s, Just e) -> Right $ diffAndToString s e
where parse = parseCalendarTime defaultTimeLocale "%C%y%m%d-%H%M"
resultString [s,e] = either ("Bad "++) id (calcDiff s e)
main = putStrLn . resultString =<< getArgs
/home ::
/haskell ::
permalink ::
rss
2006-11-05
Caught Little Birdy, Sarah Blasko, along with Tex Perkins and Tim Rogers
at Legs 11. Lots of fun in
the park, with music, wine and food -- the most relaxed gig I've ever
been to. The new Little Birdy album, Hollywood, has some real Yeah Yeah
Yeah-ish sounds, and even some Chrissie Amphlett moments.
On the topic of sound, my music of the moment must be Deerhoof
though, for sheer crazy, noisy fun.
/home ::
/music ::
permalink ::
rss
2006-11-02
Stefan made a
little joke about how sometimes Haskell code can be non-obvious.
Although his code seems pretty tame, I
wondered what it would look like @pl-ified by lambdabot. The
results were surprisingly good:
import Control.Arrow
import Data.List
order = map snd
. sortBy ((. fst)
. compare . fst)
. zipWith ((id ***) . flip (,)) [toEnum 0..]
. sortBy ((. snd) . compare . snd)
. zip [0..]
Looks about the same, right? Yes! I thought lambdabot would explode
this, and it didn't :)
The end.
/home ::
/haskell ::
permalink ::
rss