Tuesday, April 26, 2016

Finally started to use something fancy (Data.Aeson)

First time aeson user. The magic part is ToJSON/FromJSON instance. Knowing how generics works in Haskell, one could intuitively expect empty ToJSON and FromJSON instance to work as is (no need to write any specialization to serialize/de-serialize ADT) and that will be the discipline I would choose when define APIs.

{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE DeriveGeneric #-}
import qualified Data.ByteString.Lazy as L
import qualified Data.Text as Text
import Data.Text(Text)

import Data.Aeson
import GHC.Generics

data Patient = Patient {
    firstName :: Text
  , lastName :: Text
  , emailAddress :: Text
  , birthDate :: Text
  , latestBloodPressureDate :: Text
  , systolic :: Int
  , diastolic :: Int
  } deriving (Generic, Show)


instance ToJSON Patient where
instance FromJSON Patient where

patients :: L.ByteString -> Maybe [Patient]
patients = decode

main = L.getContents >>= print . patients

Wednesday, April 13, 2016

generate all combinations of given length for [1..k]


> selections 2 4
[[1,1],[1,2],[1,3],[1,4],[2,1],[2,2],[2,3],[2,4],[3,1],[3,2],[3,3],[3,4],[4,1],[4,2],[4,3],[4,4]]

selections :: Int -> Int -> [[Int]]
selections 1 k = fmap pure [1..k]
selections n k = liftA2 (:) [1..k] (selections (n-1) k)

total number of selections = k ^ n

Tuesday, April 5, 2016

Generate BST for an ordered list

It seems hard when first heard of this. However, it's way more easier they I thought:

import Data.Array
import Data.List

data BTree a = Leaf | Branch a (BTree a) (BTree a) deriving Show

-- | the type signature can be omitted, use it here for documentation
makeBST :: Ord a => [a] -> BTree a
makeBST xs = acc (listArray (1, len) (sort xs)) 1 len
  where len = length xs
        acc u i j
          | i > j = Leaf
          | i <= j = Branch (u ! k) (acc u i (pred k)) (acc u (succ k) j)
            where k = (i+j) `div` 2

The idea is extremely simple, for a (sub) list already sorted, divide it to

  [left] ++ [pivot] ++ [right]

make pivot to be the root node, then call makeBST recursively on both @left and @right, and inserted it to the root node.

I've spotted C++ implementation which made me headache, however, the Haskell version feels like a one-liner.

Guess I've found another example of my theory:

  To learn algorithm, you probably shouldn't read any code at all, not even pseudo code.

There are some outstanding books on algorithms, what I don't like is the imperative style pseudo code, and assume you have to implement the algorithm with C/C++/Java, which is really hard to understand. To me, if I tried to read into the code, I would forget the algorithm itself pretty quick, 3 month later, I forget the code altogether; Instead, tried to understand the algorithm without any code (or at least functional ones, draw graphs if necessary). It may take longer when implement some algorithms than memorizing the code, the upside is this kind of memory last really long.