Search history

Well into this year and I have very little interesting things to write about, I'm afraid. Just pasting a blurb here that shouldn't blow any minds, but speaks to how cute and easy things can be.

At work we needed to keep track of the user's n most recent searches and show them in a dropdown menu. They're first-in, first-out, but if a user selects a previous search and re-runs it, it jumps back up to the top of the history. There's no need to remove anything from the list; a history item can only be pushed out by new searches. O(n) is okay because n is small. With such convenient constraints, it was simple enough to just do this.

{-# LANGUAGE UnicodeSyntax #-}

data Queue a = Queue { limit ∷ Int, values ∷ [a] } deriving Show

enqueue ∷ Eq a ⇒ a → Queue a → Queue a
enqueue α (Queue l ω) = Queue l $ take l $ (α :) $ filter (/= α) ω

A three item queue.

q = Queue 3 []
Queue {limit = 3, values = []}

Adding two items.

enqueue 2 $ enqueue 1 $ q
Queue {limit = 3, values = [2,1]}

Bumping the first item back to the top.

enqueue 1 $ enqueue 2 $ enqueue 1 $ q
Queue {limit = 3, values = [1,2]}

Pushing old items past the limit of 3.

enqueue 4 $ enqueue 3 $ enqueue 1 $ enqueue 2 $ enqueue 1 $ q
Queue {limit = 3, values = [4,3,1]}

That's it. take and filter probably won't result in two traversals due to laziness, though it hardly matters. I like how optimistic this wound up being.