[Haskell-cafe] about Haskell code written to be "too smart"

Thomas Hartman tphyahoo at gmail.com
Wed Mar 25 16:13:00 EDT 2009


Not only is your "simpler" function easier to read, it is also more correct.

partitionsHubris xs ns = zipWith take ns . init $ scanl (flip drop) xs ns

partitionsBeginner :: [Int] -> [a] -> [[a]]
partitionsBeginner [] _         =  []
partitionsBeginner _ []         =  []
partitionsBeginner (n : ns) xs  =  head : partitionsBeginner ns tail
   where (head, tail) = splitAt n xs

Run both through testP to see why,.

testP pf = mapM_ putStrLn  [
          show . pf [3,7..] $ [1..10]
          , show . pf [3,7,11,15] $ [1..]
          , show . head . last $ pf [3,3..] [1..10^6]
        ]

Of course, I favor

partitions [] xs = []
partitions (n:parts) xs =
 let (beg,end) = splitAt n xs
 in beg : ( case end of
              [] -> []
              xs -> partitions parts xs)

which to my eyes is even easier to read (and also correct).

Pattern matching is awesome language feature. use it!


2009/3/24 Manlio Perillo <manlio_perillo at libero.it>:
> Tim Newsham ha scritto:
>>>
>>> These friends are very interested in Haskell, but it seems that the main
>>> reason why they don't start to seriously learning it, is that when they
>>> start reading some code, they feel the "Perl syndrome".
>>>
>>> That is, code written to be "too smart", and that end up being totally
>>> illegible by Haskell novice.
>>>
>>> I too have this feeling, from time to time.
>>>
>>> Since someone is starting to write the Haskell coding style, I really
>>> suggest him to take this "problem" into strong consideration.
>>
>> When you think about it, what you are saying is that Haskell programmers
>> shouldn't take advantage of the extra tools that Haskell provides.
>
> No, I'm not saying this.
>
> But, as an example, when you read a function like:
>
> buildPartitions xs ns = zipWith take ns . init $ scanl (flip drop) xs ns
>
> that can be rewritten (argument reversed) as:
>
> takeList :: [Int] -> [a] -> [[a]]
> takeList [] _         =  []
> takeList _ []         =  []
> takeList (n : ns) xs  =  head : takeList ns tail
>    where (head, tail) = splitAt n xs
>
> I think that there is a problem.
>
> The buildPartition contains too many "blocks".
> And I have read code with even more "blocks" in one line.
>
> It may not be a problem for a "seasoned" Haskell programmer, but when you
> write some code, you should never forget that your code will be read by
> programmers that can not be at your same level.
>
> I think that many Haskell programmers forget this detail, and IMHO this is
> wrong.
>
>> Haskell provides the ability to abstract code beyond what many other
>> programming systems allow.  This abstraction gives you the ability to
>> express things much more tersely.  This makes the code a lot harder to read
>> for people who are not familiar with the abstractions being used.
>
> The problem is that I have still problems at reading and understanding code
> that is too much terse...
> Because I have to assemble in my mind each block, and if there are too many
> blocks I have problems.
>
>> [...]
>
>
> Manlio
> _______________________________________________
> Haskell-Cafe mailing list
> Haskell-Cafe at haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe
>


More information about the Haskell-Cafe mailing list