Skip to content

Instantly share code, notes, and snippets.

@HirotoShioi
Last active September 16, 2018 10:57
Show Gist options
  • Save HirotoShioi/a0890680d92cc42a37eb64982e897ed4 to your computer and use it in GitHub Desktop.
Save HirotoShioi/a0890680d92cc42a37eb64982e897ed4 to your computer and use it in GitHub Desktop.
すごいH本で見落としがちだが実は重要な機能:newtype ref: https://qiita.com/HirotoShioi/items/70cd235e93dee99bf8e8
-- | ユーザー(図書館利用者)
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]
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
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
*> let bookId = 11
*> let userId = 10
-- 渡すIdの順番が間違ってる
*> JustType.borrowBook userId bookId []
Right [Record {rId = 0, rBookId = 10, rUserId = 11}]
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
*> 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}}]
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)
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