Last active
January 10, 2016 01:56
-
-
Save mitsuji/bb7285df487fdcbac3fe to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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