実例による PureScript 3 章
build の前にいくつかの module のインストールが必要だった。
$ spago install purescript-control
$ spago install purescript-maybe
$ spago install purescript-lists
$ spago build
$ spago repl
> import Data.AddressBook
> address = { street: "明治通り", city: "Shibuya", state: "Tokyo" }
> showAddress address
"明治通り, Shibuya, Tokyo"
> entry = { firstName: "Taro", lastName: "Suzuki", address: address }
> showEntry entry
"Suzuki, Taro, 明治通り, Shibuya, Tokyo"
サンプルはそのままで動いた。
module Data.AddressBook where
import Prelude
import Control.Plus (empty)
import Data.List (List (..), filter, head)
import Data.Maybe (Maybe)
type Entry = { firstName :: String, lastName :: String, address :: Address }
type Address = { street :: String, city :: String, state :: String }
type AddressBook = List Entry
showEntry :: Entry -> String
showEntry entry = entry.lastName <> ", " <>
entry.firstName <> ", " <>
showAddress entry.address
showAddress :: Address -> String
showAddress address = address.street <> ", " <>
address.city <> ", " <>
address.state
emptyBook :: AddressBook
emptyBook = empty
insertEntry :: Entry -> AddressBook -> AddressBook
insertEntry = Cons
findEntry :: String -> String -> AddressBook -> Maybe Entry
findEntry firstName lastName = head <<< filter filterEntry
where
filterEntry :: Entry -> Boolean
filterEntry entry = entry.firstName == firstName && entry.lastName == lastName
printEntry firstName lastName book
= map showEntry (findEntry firstName lastName book)
> address = { street: "明治通り", city: "Shibuya", state: "Tokyo" }
> entry = { firstName: "Taro", lastName: "Suzuki", address: address }
> book1 = insertEntry entry emptyBook
> printEntry "Taro" "Suzuki" book1
(Just "Suzuki, Taro, 明治通り, Shibuya, Tokyo")
演習 1.
head は
List Entry -> Maybe Entry
filter は
(Entry -> Boolean) -> List Entry -> List Entry
AddressBook = List Entry なので読み替え可。
演習 2.
こんなんでいいのか?
module Data.AddressBook where
import Prelude
import Control.Plus (empty)
import Data.List (List (..), filter, head)
import Data.Maybe (Maybe)
type Entry = { firstName :: String, lastName :: String, address :: Address, phoneNumber :: String }
type Address = { street :: String, city :: String, state :: String }
type AddressBook = List Entry
showEntry :: Entry -> String
showEntry entry = entry.lastName <> ", " <>
entry.firstName <> ", " <>
showAddress entry.address <> ", " <>
entry.phoneNumber
showAddress :: Address -> String
showAddress address = address.street <> ", " <>
address.city <> ", " <>
address.state
emptyBook :: AddressBook
emptyBook = empty
insertEntry :: Entry -> AddressBook -> AddressBook
insertEntry = Cons
findEntry :: String -> String -> AddressBook -> Maybe Entry
findEntry firstName lastName = head <<< filter filterEntry
where
filterEntry :: Entry -> Boolean
filterEntry entry = entry.firstName == firstName && entry.lastName == lastName
findEntryFromPhoneNumber :: String -> AddressBook -> Maybe Entry
findEntryFromPhoneNumber phoneNumber = head <<< filter filterEntry
where
filterEntry :: Entry -> Boolean
filterEntry entry = entry.phoneNumber == phoneNumber
printEntry firstName lastName book
= map showEntry (findEntry firstName lastName book)
> address = { street: "明治通り", city: "Shibuya", state: "Tokyo" }
> entry = { firstName: "Taro", lastName: "Suzuki", address: address, phoneNumber: "123-4567" }
> book1 = insertEntry entry emptyBook
> findEntryFromPhoneNumber "123-4567" book1
(Just { address: { city: "Shibuya", state: "Tokyo", street: "明治通り" }, firstName: "Taro", lastName: "Suzuki", phoneNumber: "123-4567" })
> findEntryFromPhoneNumber "345-6789" book1
Nothing
演習 3.
> import Data.List (null)
> :t null
forall (a :: Type). List a -> Boolean
import Data.List (List (..), filter, head, null)
isEntryExist :: String -> String -> AddressBook -> Boolean
isEntryExist firstName lastName = not <<< null <<< filter filterEntry
where
filterEntry :: Entry -> Boolean
filterEntry entry = entry.firstName == firstName && entry.lastName == lastName
演習 4.
> import Data.List (nubBy)
> :t nubBy
forall (a :: Type). (a -> a -> Ordering) -> List a -> List a
できた。けどもっといい書き方ありそう。
removeDuplicates :: AddressBook -> AddressBook
removeDuplicates = nubBy compareEntry
where
compareEntry :: Entry -> Entry -> Ordering
compareEntry e1 e2 =
if lastCompare == EQ then
firstCompare
else
lastCompare
where
lastCompare = compare e1.lastName e2.lastName
firstCompare = compare e1.firstName e2.firstName
この記事が気に入ったらサポートをしてみませんか?