Deprecated: The each() function is deprecated. This message will be suppressed on further calls in /home/zhenxiangba/zhenxiangba.com/public_html/phproxy-improved-master/index.php on line 456
Haskell hacking
[go: Go Back, main page]


Haskell Hacking: a journal of Haskell programming



2006-11-21

Old photographs

A newly discovered photograph of my great great grandfather's sister, emigrated to Australia in 1830. The photo is pre-1890, I'm guessing.


/home :: /random :: permalink :: rss

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

2006-11-12

More refactoring

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

Response to "Getting real with Haskell"

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

Music in the Domain

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

@pl-ising Stefan Holdermans' Code

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

Archives

Recommended

Blog Roll

Syndicate