Skip to content

Instantly share code, notes, and snippets.

@joneshf
Created January 12, 2014 17:38
Show Gist options
  • Save joneshf/8387869 to your computer and use it in GitHub Desktop.
Save joneshf/8387869 to your computer and use it in GitHub Desktop.
take
take :: Int -> [a] -> [a]
take n _ | n <= 0 = []
take _ [] = []
take n (x:xs) = x : take (n-1) xs
repeat :: a -> [a]
repeat y = ys where ys = y : ys
take 3 (repeat 1) ~>
-- This evaluates in order of the clauses of take
-- First clause
? 3 <= 0 -- Guard in the first case of take
? False -- Evaluates to False, go to next case
-- Second clause
repeat 1 => 1 : ys
-- (1:ys) /= [], so it doesn't unify with the second clause
-- Third clause
-- n == 3, x:xs = 1:ys, so it unifies
-- So we are now at
1 : take (n - 1) ys
1 : take 2 ys ~>
-- First clause
? 2 <= 0 -- Guard in the first case of take
? False -- Evaluates to False, go to next case
-- Second clause
ys => 1 : ys
-- (1:ys) /= [], so it doesn't unify with the second clause
-- Third clause
-- n == 2, x:xs = 1:ys, so it unifies
-- So we are now at
1 : 1 : take (n - 1) ys
1 : 1 : take 1 ys ~>
-- First clause
? 1 <= 0 -- Guard in the first case of take
? False -- Evaluates to False, go to next case
-- Second clause
ys => 1 : ys
-- (1:ys) /= [], so it doesn't unify with the second clause
-- Third clause
-- n == 1, x:xs = 1:ys, so it unifies
-- So we are now at
1 : 1 : 1 : take (n - 1) ys
1 : 1 : 1 : take 0 ys ~>
-- First clause
? 0 <= 0 -- Guard in the first case of take
? True -- Evaluates to True, we're done
1 : 1 : 1 : []
1 : 1 : [1]
1 : [1, 1]
[1, 1, 1]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment