import Data.List
numUniques :: (Eq a) => [a] -> Int
numUniques = length . nub
nub
はData.List
の関数
Globalにロードされてしまう
Globalにロードさせたくない場合は
import qualified Data.List
numUniques :: (Eq a) => [a] -> Int
numUniques = length . Data.List.nub
spaceが前後にある.
とspaceが前後にない.
は意味が違う
まずは各桁数の合計をたす関数を用意する
Data.Char
のdigitToInt
とshow
を使用
Prelude> :m + Data.Char
Prelude Data.Char> digitToInt '2'
2
Prelude Data.Char> digitToInt '12345'
<interactive>:4:13: parse error on input `12345'
Prelude Data.Char> show 1234567
"1234567"
import Data.Char
import Data.List
digitSum :: Int -> Int
digitSum = sum . map digitToInt . show
Data.List.find
Prelude Data.Char Data.List> :t find
find :: (a -> Bool) -> [a] -> Maybe a
firstTo40 :: Maybe Int
firstTo40 = find (\x -> digitSum x == 40) [1..]
[1..]
は無限リスト(\ )
はラムダ式
名前から電話番号を探す
phoneBook =
[("betty", "555-2938")
,("bonnie", "452-2928")
,("pasty", "493-2928")
]
findKey :: (Eq k) => k -> [(k, v)] -> Maybe v
findKey key xs = foldr (\(k,v) acc -> if key == k then Just v else acc) Noting xs
- ↑だと一致したあたいが見つかった後も探索をつづけちゃう
foldr
を見ただけで再起だとわかるからこっちのほうがわかりやすいと書いているが、わかりにくくね?
Data.List.lookup
やれば一発
lookup "pasty" phoneBook
> Just "493-2928"
名前の衝突があるので、Data.Mpp
を使用するときは必ずqualified
を使用
import qualified Data.Map as Map
phoneBook2 :: Map.Map String String
phoneBook2 = Map.fromList $
[("betty", "555-2938")
,("bonnie", "452-2928")
,("pasty", "493-2928")
]
-
先ほどの例よりも
Map
を使ったほうが速い -
$
: 右側の関数の評価を引数とするf, g: function x, y: value f x (g y) f x $ g y 上記2つは同じ
( )
が少ないとhaskellっぽいらしい -
Data.Map.Map
: 型 -
Data.Map.map
:map
関数(Data.Map.Map
が使えるようにしたmap
関数)
(そもそもMapでそんなデータ扱おうとしてること自体が間違いなんじゃ・・・。)
Prelude Data.Char Data.List Data.Map> :t Data.Map.fromList
Data.Map.fromList :: Ord k => [(k, a)] -> Map k a
Prelude Data.Char Data.List Data.Map> :t Data.Map.fromListWith
Data.Map.fromListWith
:: Ord k => (a -> a -> a) -> [(k, a)] -> Map k a
phoneBook =
[("betty", "555-2938")
,("betty", "342-2492")
,("bonnie", "452-2928")
,("pasty", "493-2928")
]
phoneBookToMap :: (Ord k) => [(k, String)] -> Map.Map k String
phoneBookToMap xs = Map.fromListWith add xs
where add number1 number2 = number1 ++ ", " ++ number2
phoneBookToMap phoneBook
-- > fromList[("betty", "342-2492, 555-2938"), ("bonnie", "452-2928"), ("pasty", "493-2928")]
- これでもできるでー
phoneBookToMap :: (Ord k) => [(k, String)] -> Map.Map k String
phoneBookToMap xs = Map.fromListWith ((++) . (++ ", ")) xs