Last active
September 16, 2018 10:57
-
-
Save HirotoShioi/a0890680d92cc42a37eb64982e897ed4 to your computer and use it in GitHub Desktop.
すごいH本で見落としがちだが実は重要な機能:newtype ref: https://qiita.com/HirotoShioi/items/70cd235e93dee99bf8e8
This file contains hidden or 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
-- | ユーザー(図書館利用者) | |
data User = User | |
{ uId :: !Integer | |
, uName :: !Text | |
} deriving (Eq, Show) | |
-- | 本 | |
data Book = Book | |
{ bId :: !Integer | |
, bAuthor :: !Text | |
, bTitle :: !Text | |
} deriving (Eq, Show) | |
-- | 貸出履歴 | |
data Record = Record | |
{ rId :: !Integer | |
, rBookId :: !Integer | |
, rUserId :: !Integer | |
} deriving (Eq, Show) | |
type LibraryDB = [Record] |
This file contains hidden or 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.Text (Text) | |
data User = User | |
{ uId :: !Integer | |
, uName :: !Text | |
} deriving (Eq, Show) | |
data Book = Book | |
{ bId :: !Integer | |
, bAuthor :: !Text | |
, bTitle :: !Text | |
} deriving (Eq, Show) | |
data Record = Record | |
{ rId :: !Integer | |
, rBookId :: !Integer | |
, rUserId :: !Integer | |
} deriving (Eq, Show) | |
type LibraryDB = [Record] | |
borrowBook :: Integer -> Integer -> LibraryDB -> Either Record LibraryDB | |
borrowBook bookId userId db = | |
case lookupRecordByBookId bookId db of | |
Just record -> Left record | |
Nothing -> do | |
let newRecordId = getNewRecordId db | |
newRecord = Record newRecordId bookId userId | |
return $ newRecord:db | |
where | |
getNewRecordId :: [Record] -> Integer | |
getNewRecordId = fromIntegral . length | |
lookupRecordByBookId :: Integer -> LibraryDB -> Maybe Record | |
lookupRecordByBookId bookId = lookupRecord bookId rBookId | |
lookupRecordById :: Integer -> LibraryDB -> Maybe Record | |
lookupRecordById recordId = lookupRecord recordId rId | |
lookupRecord :: (Eq a) => a -> (Record -> a) -> LibraryDB -> Maybe Record | |
lookupRecord _ _ [] = Nothing | |
lookupRecord someId getter (r:rs) | |
| someId == getter r = Just r | |
| otherwise = lookupRecord someId getter rs | |
This file contains hidden or 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.Text (Text) | |
type UserId = Integer | |
data User = User | |
{ uId :: !UserId | |
, uName :: !Text | |
} deriving (Eq, Show) | |
type BookId = Integer | |
data Book = Book | |
{ bId :: !BookId | |
, bAuthor :: !Text | |
, bTitle :: !Text | |
} deriving (Eq, Show) | |
type RecordId = Integer | |
data Record = Record | |
{ rId :: !RecordId | |
, rBookId :: !BookId | |
, rUserId :: !UserId | |
} deriving (Eq, Show) | |
type LibraryDB = [Record] | |
borrowBook :: BookId -> UserId -> LibraryDB -> Either Record LibraryDB | |
borrowBook bookId userId db = | |
case lookupRecordByBookId bookId db of | |
Just record -> Left record | |
Nothing -> do | |
let newRecordId = getNewRecordId db | |
newRecord = Record newRecordId bookId userId | |
return $ newRecord:db | |
where | |
getNewRecordId :: [Record] -> RecordId | |
getNewRecordId = fromIntegral . length | |
lookupRecordByBookId :: BookId -> LibraryDB -> Maybe Record | |
lookupRecordByBookId bookId = lookupRecord bookId rBookId | |
lookupRecordById :: RecordId -> LibraryDB -> Maybe Record | |
lookupRecordById recordId = lookupRecord recordId rId | |
lookupRecord :: (Eq a) => a -> (Record -> a) -> LibraryDB -> Maybe Record | |
lookupRecord _ _ [] = Nothing | |
lookupRecord someId getter (r:rs) | |
| someId == getter r = Just r | |
| otherwise = lookupRecord someId getter rs | |
This file contains hidden or 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
*> let bookId = 11 | |
*> let userId = 10 | |
-- 渡すIdの順番が間違ってる | |
*> JustType.borrowBook userId bookId [] | |
Right [Record {rId = 0, rBookId = 10, rUserId = 11}] |
This file contains hidden or 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.Text (Text) | |
newtype UserId = UserId | |
{ getUserId :: Integer | |
} deriving (Eq, Show) | |
data User = User | |
{ uId :: !UserId | |
, uName :: !Text | |
} deriving (Eq, Show) | |
newtype BookId = BookId | |
{ getBookId :: Integer | |
} deriving (Eq, Show) | |
data Book = Book | |
{ bId :: !BookId | |
, bAuthor :: !Text | |
, bTitle :: !Text | |
} deriving (Eq, Show) | |
newtype RecordId = RecordId | |
{ getRecordId :: Integer | |
} deriving (Eq, Show) | |
data Record = Record | |
{ rId :: !RecordId | |
, rBookId :: !BookId | |
, rUserId :: !UserId | |
} deriving (Eq, Show) | |
type LibraryDB = [Record] | |
borrowBook :: BookId -> UserId -> LibraryDB -> Either Record LibraryDB | |
borrowBook bookId userId db = | |
case lookupRecordByBookId bookId db of | |
Just record -> Left record | |
Nothing -> do | |
let newRecordId = getNewRecordId db | |
newRecord = Record newRecordId bookId userId | |
return $ newRecord:db | |
where | |
getNewRecordId :: [Record] -> RecordId | |
getNewRecordId = RecordId . fromIntegral . length | |
lookupRecordByBookId :: BookId -> LibraryDB -> Maybe Record | |
lookupRecordByBookId bookId = lookupRecord bookId rBookId | |
lookupRecordById :: RecordId -> LibraryDB -> Maybe Record | |
lookupRecordById recordId = lookupRecord recordId rId | |
lookupRecord :: (Eq a) => a -> (Record -> a) -> LibraryDB -> Maybe Record | |
lookupRecord _ _ [] = Nothing | |
lookupRecord someId getter (r:rs) | |
| someId == getter r = Just r | |
| otherwise = lookupRecord someId getter rs |
This file contains hidden or 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
*> let bookId = BookId 11 | |
*> let userId = UserId 10 | |
*> Newtype.borrowBook bookId userId [] | |
Right [Record {rId = RecordId {getRecordId = 0}, rBookId = BookId {getBookId = 11}, rUserId = UserId {getUserId = 10}}] |
This file contains hidden or 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
newtype BookId = BookId | |
{ getBookId :: Integer | |
} deriving (Eq, Show) | |
newtype Title = Title | |
{ getTitle :: Text | |
} deriving (Eq, Show) | |
newtype Name = Name | |
{ getName :: Text | |
} deriving (Eq, Show) | |
data Book = Book | |
{ bId :: !BookId | |
, bAuthor :: !Name | |
, bTitle :: !Title | |
} deriving (Eq, Show) |
This file contains hidden or 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
evilFun :: BookId -> UserId -> Integer | |
evilFun bookId userId = | |
let bookNum = getBookId bookId -- Integer | |
userNum = getUserId userId -- Integer | |
in bookNum + userNum -- What...? |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment