Does Haskell naturally break off into multi-tiered development?

Submitted by metaperl on Fri, 06/02/2006 - 11:11am.

It seems that Haskell's ethic for putting a gate between I/O and its referentially transparent and strongly-typed functions means that the concept of
multi-tiered architectures is something of a no-brainer.

There are a few web frameworks and web apps in Haskell - HApps, Flippi... do these map naturally and easily onto multiple tiers?

Are there other examples of multiple-tiered apps for Haskell?

Haskell - guardian of functional purity but violator of software engineering purity?

Submitted by metaperl on Sat, 05/13/2006 - 2:07pm.

Yesterday, after 1 year of studying Haskell, I tried to write my first program involving I/O. I decided to convert a Perl program that I had written which provides lookup of state names via their 2-letter code and vice-versa. A day later, I had something written, but was worried because all of my functions were using fmap to pull things out of the IO monad. In other words, my entire library reeked of I/O.

The next day, Cale Gibbard wrote a very nice version of my program which relegated the IO to a single function.

But the thing is, you still have to use my module from the main program with the awareness that the data is coming from an IO source. Now, a basic principle of software engineering is to separate the interface from the implementation. There is no way to use the Haskell implementation of my module without full knowledge that said module is returning me data that is coming from I/O... outside of using something called unsafeIO which I know nothing about.

why does this matter?
Let's say I have a function which does something to a list of functions of type (String -> String) but one of the functions has to open a file to get its string:

sfnProc :: [(String -> String)] -> [Int]
sfnProc = map (\f -> length f)

so the problem becomes that the one function that returns a string via I/O cannot be used opaquely: the referential transparency of Haskell is killing need for opaque API of software engineering.

Data ByteString Lazy is sweet

Submitted by metaperl on Sat, 05/13/2006 - 1:26pm.

outdoes sed and probably Perl too:
check it out it's great for processing huge data files that won't fit in memory.

It's time to start coding Haskell

Submitted by metaperl on Fri, 05/12/2006 - 11:06am.

the study period is finished. no more book learning. let the coding begin.

Perl: the super-convenient pseudo-functional language

Submitted by metaperl on Fri, 05/12/2006 - 10:55am.

I work at a place where we show adult models online. I was building our monthly newsletter and realized that of the 30 models who I could choose for the newsletter, not all of them had all 4 required pictures.

So I needed to hit our content server and see if a model had all 4 pictures. My knowledge of functional programming came in handy, but look how easy this was to code in Perl:


use LWP::Simple;

my @stream = qw(

# type ModelName = String
# type ImageNumber = Int
# type URLString = String
# img :: ModelName -> ImageNumber -> URLString
sub img {
my $s = shift;
my $i = shift;

my $prefix = substr $s, 0, 1 ;
$prefix = uc $prefix;


# does a model have all 4 images?
# good_imgs :: [ URLString ] -> Bool
sub good_imgs {
my $s = shift;
for my $i (1..4) {
my $img = img($s, $i), $/;
return undef unless get($img) ;
return 1;

# grep is like Haskell's filter
my @ok = grep { good_imgs($_) } @stream ;

# print the models with all 4 images
print join "\n", @ok ;

This is my first time seeing how great _Haskell_ really is. Those type signatures make my Perl self-documenting. But the thing is, there is nothing close to libwww-perl for Haskell. It not only makes HTTP requests but comes with a pragmatic parser for everyday HTML.

Another thing is look how I could list the model names without bothering with quotes around the strings. The qw() operator in Perl allows one to input a list of strings without quotes by simply separating them with whitespace.

unwords with optional record separator is hard to write?

Submitted by metaperl on Thu, 05/11/2006 - 10:29am.

I was chatting with Cale on #haskell and said that unwords should be configurable: it should take an optional argument specifying what to separate the elements of the list with.

He said that would be hard.

It is a common thing in Perl and Lisp for a function to assume defaults if you don't specify things.

I guess the best thing to do in Haskell is to always expect the separator to be specified and have the function curryable on the input list to be unworded:

unwords :: String -> [a] -> String
unwords sep lis = blah blah

extending howManyEqual

Submitted by metaperl on Mon, 05/08/2006 - 5:50pm.

howManyEqual a b c = fromEnum(a == b) + fromEnum(b == c) + fromEnum(a == c)

how would I write howManyEqualFour a b c d

abstracting the abstract

Submitted by metaperl on Thu, 05/04/2006 - 4:49pm.

Does anyone have any suggestions for making this code even more abstract?

-- concrete approach
twoThreeA1 = above (sideBySide white blackRectangle) (sideBySide blackRectangle white)
twoThreeA2 = sideBySide (above white blackRectangle) (above blackRectangle white)

-- abstract approach
twoThreeAg joiner builder = joiner (builder white blackRectangle) (builder blackRectangle white)
twoThreeA1g = twoThreeAg above sideBySide
twoThreeA2g = twoThreeAg sideBySide above

-- can we get more abstract?

The saga of my quest to understand the State monad

Submitted by metaperl on Wed, 04/26/2006 - 1:55am.

Part I:

-- Given this:

fmap :: (a -> b) -> (State s a) -> (State s b)
fmap f (State m) = State (onVal f . m)
where onVal f (x, s) = (f x, s)

-- problem 1: the type signature says that the ultimate return value is
-- (State s b) which would be this function : (\s -> (b,s))
-- However, the type of onVal is this:
-- :t onVal
-- onVal :: (a -> a1) -> (a, b) -> (a1, b)
-- In other words, it is just a 2-tuple. It is not clear that a 2-tuple
-- satisfies the expected type (State s b)

-- problem 2: I don't understand the expression (onVal f . m)
-- is this onval (f . m) or (onVal f) . m

modelling Camels : I started the convo, so I gotta chronicle it

Submitted by metaperl on Mon, 04/24/2006 - 8:51pm.

[19:43:51] /metaperl/ I was trying to make the leap from data Sheep = (name::String, mother::Maybe Sheep, father::Maybe Sheep) to camels....
[19:44:19] /Cale/ (that is, not quite fields)
[19:44:42] /sjanssen_/ metaperl: perhaps a good encoding is "data Camel a b c = Camel a b (Maybe c)"
[19:44:55] /metaperl/ sjanssen_: very clever!
[19:44:57] /metaperl/ :)
[19:45:42] /metaperl/ I like to name the type and data constructor distinctly though: data CamelType a b c = Camel a b (Maybe c)
[19:47:14] /Cale/ data Camel a b = Dromedary a | Bactrian a b
[19:47:45] /metaperl/ nice Cale
[19:49:25] /Cale/ I'm not sure what kind of Camel would have 3 humps though.
[19:49:31] /goltrpoat/ an Objective one.
[19:49:41] /Korollary/ A souped-up camel
[19:49:44] /Korollary/ long range
[19:49:52] /sjanssen_/ a camel with a massive tumor?
[19:50:20] /Cale/ an intercontinental ballistic camel
[19:50:29] /Lokadin/ lol
[19:51:06] /Cale/ the extra 'hump' is a warhead
[19:51:47] /goltrpoat/ embedded by INRIA