結城浩のHaskell日記 RSSフィード

2006-06-15

map.map map.map - 結城浩のHaskell日記 を含むブックマーク

http://haskell.g.hatena.ne.jp/taninsw/20060614/p3 を読んで、最初map.mapの意味がわからなかった。

["alice","bobby"]がリストのリストだと気づくのに30秒くらいかかった。やれやれ。

import Char

a = toUpper 'a'
b = map toUpper "alice"
c = (map.map) toUpper ["alice","bobby"]

型クラス 型クラス - 結城浩のHaskell日記 を含むブックマーク

ふつけるp.238まで読みました。

type宣言 type宣言 - 結城浩のHaskell日記 を含むブックマーク

ふつけるp.235まで読みました。

type宣言は型に別名をつけます。データコンストラクタは導入されません。

module Main where

type Name = String
type Mail = String

data Person = Person { name :: Name, mail :: Mail }

toString :: Person -> String
toString (Person { name = n, mail = m }) = "" ++ n ++ " <" ++ m ++ ">"

alice = Person "alice" "alice@example.com"
bill = Person "William" "bill@example.com"

isNameBasedMail :: Person -> Bool
isNameBasedMail (Person { name = n, mail = m })
    = (n ++ "@") `isPrefixOf` m
    where
        [] `isPrefixOf` _ = True
        _  `isPrefixOf` [] = False
        (x:xs) `isPrefixOf` (y:ys)
            | x == y = xs `isPrefixOf` ys
            | otherwise = False

main = do
    print $ toString alice
    print $ toString bill
    print $ name alice
    print $ mail alice
    print $ isNameBasedMail alice
    print $ isNameBasedMail bill

実行結果です。

*Main> main
"alice <alice@example.com>"
"William <bill@example.com>"
"alice"
"alice@example.com"
True
False

どう考えても、上のisPrefixOfはごたごたしています。改良。

x `isPrefixOf` y = x == (take (length x) y)

もう少し。

isPrefixOf x y = (==) x $ take (length x) y

もう少し。

isPrefixOf x = (x==) . take (length x)

もう眠い。

追記:IO ()さんからコメントがありました。感謝。

isPrefixOf xs ys = and $ zipWith (==) (map Just xs) (map Just ys ++ repeat Nothing)

おもしろいですね。以下が新鮮でした。

  • Justもmapできる。
  • 無限列と有限列をzipWithする(そして有限列を得る)。
  • パディングとしてrepeat Nothingを使う。
  • [Bool]を作っておき、全部OKかをandで調べる。

ありがとうございます。

…はっ!IO ()さんの方法なら、(途中で失敗する場合の)無限列にも使えるんですね!

isPrefixOf xs ys = and $ zipWith (==) (map Just xs) (map Just ys ++ repeat Nothing)

xs = repeat 'X'
t = isPrefixOf ("abX" ++ xs) ("abc" ++ xs)

追記:http://haskell.g.hatena.ne.jp/taninsw/20060616/p2 の解説がすごくよくわかる。

IO ()IO ()2006/06/15 16:56length が何となく好きになれないので違う書き方してみました。
isPrefixOf xs ys = and $ zipWith (==) (map Just xs) (map Just ys ++ repeat Nothing)

IO ()IO ()2006/06/16 01:17http://hpcgi2.nifty.com/1to100pen/wiki/wiki.cgi?p=%CB%E8%C6%FCHaskell の 2006-05-11 でも (++ repeat Nothing) . (map Just) を使いました。