Wednesday, 22nd October 2014.

Posted on Thursday, 9th September 2010 by charpi

My post don’t pretend to be a complete tutorial on Haskell but just a sum up of my learning experience. My main objective is to understand this language, to see its strengths and its weakness.

To learn a new language, I always found funny to try to create a simple unittest framework.

Writing such framework can be tedious or very easy (thanks erlang), so such experiment give me a good overview of the language and how easy I can learn it. I’ve decided to do the same exercise with Haskell.

Goal: Write a function which counts the number of occurrence of a character in a string

Let’s start to write a module with one test case.

module CharpiLib_test where
import CharpiLib

test_empty_string = (0 == occurence 'x' "")

and the corresponding dumb implementation

module CharpiLib where

occurence :: Char -> String -> Integer
occurence _ _ = 0

This code compile and can be executed

charpi@home:~/haskell/unittest$ ghci 
GHCi, version 6.10.4: http://www.haskell.org/ghc/  :?  for help
Loading package ghc-prim ... linking ... done.
Loading package integer ... linking ... done.
Loading package base ... linking ... done.
Prelude> :load CharpiLib_test.hs
[1 of 2] Compiling CharpiLib        ( CharpiLib.hs, interpreted )
[2 of 2] Compiling CharpiLib_test   ( CharpiLib_test.hs, interpreted )
Ok, modules loaded: CharpiLib_test, CharpiLib.
*CharpiLib_test> test_empty_string
True
*CharpiLib_test> 

For the exercise, I add several test cases in a single step

module CharpiLib_test where
import CharpiLib

test_empty_string =  (0 == (occurence 'x' ""))

test_char_not_found = (0 == (occurence 'x' "hello world"))

test_one_occurence = (1 == (occurence 'h' "hello world"))

test_sevaral_occurence = (3 == (occurence 'l' "hello world"))

and execute each tests

*CharpiLib_test> :load CharpiLib_test.hs
[1 of 2] Compiling CharpiLib        ( CharpiLib.hs, interpreted )
[2 of 2] Compiling CharpiLib_test   ( CharpiLib_test.hs, interpreted )
Ok, modules loaded: CharpiLib_test, CharpiLib.
*CharpiLib_test> test_empty_string
True
*CharpiLib_test> test_one_occurence
False
*CharpiLib_test> test_sevaral_occurence
False
*CharpiLib_test> 

I can execute each test case one by one but I need something to run all the test functions in one phase.
Let’s add a function returning the list of all my test cases

suite = [test_empty_string,
         test_char_not_found,
         test_one_occurence,
         test_sevaral_occurence]
*CharpiLib_test> :load CharpiLib_test.hs
[1 of 2] Compiling CharpiLib        ( CharpiLib.hs, interpreted )
[2 of 2] Compiling CharpiLib_test   ( CharpiLib_test.hs, interpreted )
Ok, modules loaded: CharpiLib_test, CharpiLib.
*CharpiLib_test> suite
[True,True,False,False]
*CharpiLib_test> 

When I evaluate the function suite, each function of the list are evaluated and I got a final result. The example isn’t very clear but I guess that some Lazy evaluations have been made.
Lazy evaluation will be detailed in a next post. As Haskell and Erlang don’t evaluate functions in the same way, you really need to understand this notion if you want to use it efficiently.

Let’s finish my very simple unit test framework by adding a description to the test cases and by finishing on an exception if an error occurs.

module CharpiLib_test where
import CharpiLib

test_empty_string =  ("Test empty string",
                      (0 == (occurence 'x' "")))

test_char_not_found = ("No character found",
                       (0 == (occurence 'x' "hello world")))

test_one_occurence = ("One character found",
                      (1 == (occurence 'h' "hello world")))

test_sevaral_occurence = ("More than one character found",
                          (3 == (occurence 'l' "hello world")))

suite = [test_empty_string,
         test_char_not_found,
         test_one_occurence,
         test_sevaral_occurence]

run =  [ assert t | t <- suite]

assert (_,True) = True
assert (description, False) = error (description ++ ": Assertion failed")
*CharpiLib_test> :load CharpiLib_test.hs
[1 of 2] Compiling CharpiLib        ( CharpiLib.hs, interpreted )
[2 of 2] Compiling CharpiLib_test   ( CharpiLib_test.hs, interpreted )
Ok, modules loaded: CharpiLib_test, CharpiLib.
*CharpiLib_test> run
[True,True,*** Exception: One character found: Assertion failed
*CharpiLib_test> 

and now the implementation

module CharpiLib where

occurence char string =  do_occurence char string 0

do_occurence _ [] acc = acc
do_occurence c (x:xs) acc
     | c == x  = do_occurence c xs (acc+1)
     | c /= x = do_occurence c xs acc
*CharpiLib_test> :load CharpiLib_test.hs
[1 of 2] Compiling CharpiLib        ( CharpiLib.hs, interpreted )
[2 of 2] Compiling CharpiLib_test   ( CharpiLib_test.hs, interpreted )
Ok, modules loaded: CharpiLib_test, CharpiLib.
*CharpiLib_test> run
[True,True,True,True]
*CharpiLib_test> 

Done :-)

Conclusion: I need more time to learn haskell and how to use it efficiently.

  • Type errors are still very obscure for me.
  • Monads is the last frontier

Tags: ,
Posted in Uncategorized | Comments (3,285)

Posted on Saturday, 28th August 2010 by charpi

Remembering  ”The pragmatic programmer: Fro, Journeyman to Master”, each developer should learn a new language each year.

This year, I will give its chance to Haskell.

Why Haskell ?

Scala was a candidate for this year but Haskell has a strong reputation in the functional world. I came to functional with Erlang because of its concurrent and distribution aspects and I have the feeling that I miss some fundamental notions.

A lot of people seems to like (to venerate) types. Personally, I can live without type definition even if I recognize some benefit as documentation support when you distribute a library. A language like Haskell has a very strong type system and it seems to be construct around this system system, so it could be the opportunity to play with types and to discover their benefit.

Haskell has also an advantage over Erlang. It generates native code. With native code, you can deploy an application without thinking “Does my target system get the VM ?”. For utility programs, native code tends to offer better performance.

The first time I heard about Haskell was in 2003 when I was testing some innovative DVCS: GNU Arch and Darcs. Darcs is written in Haskell.

In the following weeks, I hope to have time to write about my first steps with Haskell.

Tags: ,
Posted in Uncategorized | Comments (3,548)

Posted on Sunday, 21st February 2010 by charpi

Bored to switch code between my private subversion repository and git-hub for my open-source projects, I decided to use exclusively git-hub for them.

My trac wiki pages are also moved to git-hub for improve the documentation of those projects.

Tags: , ,
Posted in Uncategorized | Comments (2,031)

Posted on Monday, 1st June 2009 by charpi

XP Days conferences (Switzerland and France) are over and now I can be
back to coding.

I have just published a new version of the erlang client to selenium
server.
You can download it here.

Nothing really new in this version:

  • Support for seleniun-server 1.0
  • Support OTP R12 and OTP R13
  • New build system based on rake.
  • Comments are welcome

    Tags: , ,
    Posted in Uncategorized | Comments (2,761)

    Posted on Wednesday, 27th May 2009 by charpi

    XP Day 2009 conference in Paris is over. Here are the slides of the presentation I made with Sylvain.

    Tags: , ,
    Posted in Uncategorized | Comments (3,549)

    About me Downloads IPhone