Spelunking series: Haskell

TODO:
* Problem 7

I got 99 problems…

Ooooh boy. This is gonna be huge.

It’s 2 am in the morning and I’ve just decided to try solving the 99 Haskell Problems. I’ve tried to grok Haskell on and off for at least three times now and I still haven’t gotten as far as monads. That’s a great thing, because I’m getting fed up at not being able to code every day and Haskell is as good as it’s gonna get.

So let’s get started.

Problem 01 (2016-04-28 02:07-02:40)

The first problem is to return the tail of a list. Armed with:

ghc main.hs
./main

…I get to work. Now I haven’t seen Haskell in n years so it’s gonna take me a while to do this. Let’s see:

main = do
     print (last [1, 2, 3, 4]) -- 4
     print (last ['x','y','z']) -- 'z'

That gave me a headache. Moving on…

Problem 02 (2016-04-28 02:40-02:47)

I just found out about this:

runhaskell main.hs

…and will be using it for the remainder of this post.

Anyway, the current task is to get the penultimate element from a list. Let’s see:

main = do
     print $ last $ init [1..4] -- 3
     print $ last $ init ['a'..'z'] -- 'y'

…and we’re done.

Problem 03 (2016-04-28 02:47-02:56)

The current problem is indexing a list (starting from 1). Let’s see:

main = do
     print $ [1, 2, 3] !! (2-1) -- 2
     print $ "haskell" !! (5-1) -- 'e'

This is borderline cheating but, hey, whatever works right?

Problem 04 (2016-04-28 02:56-03:09)

Okay, let’s try and shake things up. From now on, I am restricting my use of Prelude to the following functions: map, filter, foldl’ (the non-lazy version of foldl), and foldr. Hopefully this teaches me integrity and character. The current problem is to find the length of a list. This should be easy:

main = do
     print $ (foldr (\x acc -> acc + 1) 0 [123, 456, 789]) -- 3
     print $ (foldr (\x acc -> acc + 1) 0 "Hello, world!") -- 13

My time is wasted editing things.

Problem 05 (2016-04-28 03:12-03:15)

The current problem is to reverse a list:

_reverse [] = []
_reverse (x:xs) = (_reverse xs) ++ [x]

main = do
     print $ _reverse "A man, a plan, a canal, panama!" -- "!amanap ,lanac a ,nalp a ,nam A"
     print $ _reverse [1,2,3,4] -- [4,3,2,1]

That was longer than expected. I wonder if this can be done using anonymous functions. Hmm…

EDIT (2016-04-28 03:18):

main = do
     print $ foldr (\x acc -> acc ++ [x]) [] "A man, a plan, a canal, panama!"
     print $ foldr (\x acc -> acc ++ [x]) [] [1,2,3,4]

Uses anonymous functions but a bit shorter than the original one.

I’m going to take a nap and resume this later.

Problem 06 (2016-04-29 08:27-08:31)

Slept in yesterday. Still feel like crap. Anyway, the current problem wants me to decide whether or not a given string is a palindrome:

main = do
     print $ [1,2,3] == (foldr (\x acc -> acc ++ [x]) [] [1,2,3]) -- False
     print $ "madamimadam" == (foldr (\x acc -> acc ++ [x]) [] "madamimadam") -- True
     print $ [1,2,4,8,16,8,4,2,1] == (foldr (\x acc -> acc ++ [x]) [] [1,2,4,8,16,8,4,2,1]) -- True

These lines are getting longer.

A quick aside

Haskell on Arch Linux is hell on Earth. There exists something called “cabal dependency hell” which I will neglect to explain because I don’t really understand how one of the most sophisticated group of hackers on Earth has not yet engineered a package manager that Simply Works. Lone wolf syndrome? Not qualified enough to comment on it. Nevertheless, there’s a way out of the pit and it starts when you cd into your project directory and do:

# Generates .cabal file used by cabal build
cabal init

# Initialises sandbox, installs necessary
# packages, and builds your project
cabal sandbox init
cabal install --only-dependencies
cabal build

And when you want to install a particular package in the sandbox, just do:

cabal install --require-sandbox <package-name>

Definitions

Palindrome
a word/string/list that’s the same forwards and backwards; e.g., “timtom motmit”
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s