Skip to content

Instantly share code, notes, and snippets.

@mitsuji
Last active January 10, 2016 01:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mitsuji/bb7285df487fdcbac3fe to your computer and use it in GitHub Desktop.
Save mitsuji/bb7285df487fdcbac3fe to your computer and use it in GitHub Desktop.
import Data.Either (isLeft)
type Err = String
type ID = Int
type Rank = Int
type Name = String
type RankDB = [(Rank,ID)]
type NameDB = [(ID,Name)]
idFromRank :: RankDB -> Rank -> Either Err ID
idFromRank db rk =
case lookup rk db of
Nothing -> Left $ "id of rank " ++ (show rk) ++ " was not found."
Just id -> Right id
nameFromId :: NameDB -> ID -> Either Err Name
nameFromId db id =
case lookup id db of
Nothing -> Left $ "name of id " ++ (show id) ++ " was not found."
Just name -> Right name
topThree :: RankDB -> NameDB -> Either Err (Name,Name,Name)
topThree rdb ndb =
let eitherId1 = idFromRank rdb 1
in
if isLeft eitherId1 then Left $ fromLeft eitherId1
else
let eitherName1 = nameFromId ndb $ fromRight eitherId1
in
if isLeft eitherName1 then Left $ fromLeft eitherName1
else
let eitherId2 = idFromRank rdb 2
in
if isLeft eitherId2 then Left $ fromLeft eitherId2
else
let eitherName2 = nameFromId ndb $ fromRight eitherId2
in
if isLeft eitherName2 then Left $ fromLeft eitherName2
else
let eitherId3 = idFromRank rdb 3
in
if isLeft eitherId3 then Left $ fromLeft eitherId3
else
let eitherName3 = nameFromId ndb $ fromRight eitherId3
in
if isLeft eitherName3 then Left $ fromLeft eitherName3
else Right (
fromRight eitherName1,
fromRight eitherName2,
fromRight eitherName3
)
where
fromLeft (Left x) = x
fromRight (Right x) = x
topThreeC :: RankDB -> NameDB -> Either Err (Name,Name,Name)
topThreeC rdb ndb =
case idFromRank rdb 1 of
Left e -> Left e
Right id1 -> case nameFromId ndb id1 of
Left e -> Left e
Right n1 -> case idFromRank rdb 2 of
Left e -> Left e
Right id2 -> case nameFromId ndb id2 of
Left e -> Left e
Right n2 -> case idFromRank rdb 3 of
Left e -> Left e
Right id3 -> case nameFromId ndb id3 of
Left e -> Left e
Right n3 -> Right (n1,n2,n3)
topThreeM :: RankDB -> NameDB -> Either Err (Name,Name,Name)
topThreeM rdb ndb = do
id <- idFromRank rdb 1
n1 <- nameFromId ndb id
id <- idFromRank rdb 2
n2 <- nameFromId ndb id
id <- idFromRank rdb 3
n3 <- nameFromId ndb id
return (n1,n2,n3)
main = do
print $ topThree [(1,101),(2,102),(3,103)] [(101,"1st"),(102,"2nd"),(103,"3rd")]
print $ topThree [(1,101),(4,102),(3,103)] [(101,"1st"),(102,"2nd"),(103,"3rd")]
print $ topThree [(1,101),(2,102),(3,103)] [(101,"1st"),(104,"4th"),(103,"3rd")]
print $ topThreeC [(1,101),(2,102),(3,103)] [(101,"1st"),(102,"2nd"),(103,"3rd")]
print $ topThreeC [(1,101),(4,102),(3,103)] [(101,"1st"),(102,"2nd"),(103,"3rd")]
print $ topThreeC [(1,101),(2,102),(3,103)] [(101,"1st"),(104,"4th"),(103,"3rd")]
print $ topThreeM [(1,101),(2,102),(3,103)] [(101,"1st"),(102,"2nd"),(103,"3rd")]
print $ topThreeM [(1,101),(4,102),(3,103)] [(101,"1st"),(102,"2nd"),(103,"3rd")]
print $ topThreeM [(1,101),(2,102),(3,103)] [(101,"1st"),(104,"4th"),(103,"3rd")]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment