Haskellをラクガク

2006-09-22Haskellでよかった

第6章 基本的な値 - リスト 02:21

ワリと序盤から出てきたリストについては、ここではそれほど新しいトピックはないかな。多分おさえておくべきは「:」(コロン)演算子

main = do   
            print (1:2:3:[])
            print (1:2:(3:[]))
            print (1:2:[3])
            print (1:(2:[3]))
            print (1:[2,3])
            print ([1,2,3])
>colon
[1,2,3]
[1,2,3]
[1,2,3]
[1,2,3]
[1,2,3]
[1,2,3]

これはこれで良いのだけれども、print引数を括弧でくくらないとエラーになるのはナゼだろう。

colon.hs:3:12:
    Couldn't match `[]' against `IO'
      Expected type: []
      Inferred type: IO
    In a 'do' expression: print (1 : (2 : (3 : [])))
    In the definition of `main':
        main = do
                 (print 1) : (2 : (3 : []))
                 print (1 : (2 : (3 : [])))
                 print (1 : (2 : [3]))
                 print (1 : (2 : [3]))
                 print (1 : [2, 3])
                 print ([1, 2, 3])

nobsunnobsun2006/10/05 15:01print [1,2,3] は()で括らなくても大丈夫.
関数適用の結合力がどの中置オペレータよりも結合力が強いので,
print 1:[2,3] は (print 1):[2,3] と解釈されてしまう.
これを防ぐために,print (1:[2,3]) と括弧が必要になる.

2006-09-18久々のHaskell

第6章 基本的な値 - 数値 00:43

ここからは難しくなりそうなので、細かいところを確かめつつやっていこうかと。まずは数値について。

IntとIntegerが違うってホント?

a = (16::Integer)
b = (3::Int)
c = a+b
main = print c
IntOrInteger.hs:3:6:
    Couldn't match `Integer' against `Int'
      Expected type: Integer
      Inferred type: Int
    In the second argument of `(+)', namely `b'
    In the definition of `c': c = a + b

あら、ホントだ。どうにかしてくれても良さそうなもんだけど、Haskellの型はかなり厳密なものらしい。

でも、

a = (16::Integer)
main = print (a+3)
19

これはOK。つまり、数値リテラル文脈によって変換されるけど、一旦型を決めてしまうとIntとIntegerですら互換性がないみたい。

リテラルだけど型を付けてやると、

a = (16::Integer)
main = print (a+(3::Int))
IntOrInteger.hs:2:17:
    Couldn't match `Integer' against `Int'
      Expected type: Integer
      Inferred type: Int
    In the expression: 3 :: Int
    In the second argument of `(+)', namely `(3 :: Int)'

怒られる。

基本的な値 - 文字列 01:07

文字といったらChar。文字列といったら[Char]。[Char]の別名はString。これは結構分かりやすい。JavaみたいにStringだけやけに特別だったりしないところが良い。

a = "hogehoge"
b = "foobar"::String
c = ['f','o','o','b','a','r']::[Char]
main = do   print $ "hogehoge" == a
            print $ b == c
True
True

Haskellの「==」は同値かどうかを判定するものなので、イマイチ面白みに欠ける…。のでIntとIntegerだったらどうかというと、

a = 3::Integer
b = 4::Int
main = print $ a==b
IntEqInteger.hs:3:18:
    Couldn't match `Integer' against `Int'
      Expected type: Integer
      Inferred type: Int
    In the second argument of `(==)', namely `b'
    In the second argument of `($)', namely `a == b'

怒られる。

基本的な値 - タプル 01:27

複数の値を纏めて扱うタプル。タプルいいよな。でもタプルが組み込まれている言語ってPythonくらいしか知らないけど。

ということで、同値性チェック。

a = (3::Int,"hoge")
b = (3, "hoge")
c = (3::Integer, "hoge")

main = do   print $ a == b
            print $ b == c
            print $ c == a
TeqT.hs:6:25:
    Couldn't match `Int' against `Integer'
      Expected type: (Int, [Char])
      Inferred type: (Integer, [Char])
    In the second argument of `(==)', namely `c'
    In the second argument of `($)', namely `b == c'

あれ?「b == c」でダメか。「c == a」でダメって怒られると予想したんだけど…。タプルに数値リテラル適用すると、Intになっちゃうってことかな。それとも、先に「a == b」の評価をしたが故にfst bがIntと思われちゃったのかな。

ということで、「a == b」と「b == c」の実行順序を入れ替えてみる。

a = (3::Int,"hoge")
b = (3, "hoge")
c = (3::Integer, "hoge")

main = do   print $ b == c
            print $ a == b
            print $ c == a
TeqT.hs:6:25:
    Couldn't match `Int' against `Integer'
      Expected type: (Int, [Char])
      Inferred type: (Integer, [Char])
    In the second argument of `(==)', namely `b'
    In the second argument of `($)', namely `a == b'

やっぱり「a == b」で型が違うと怒られる。だから、bの型はIntegerなんだろう。数値リテラルみたいに文脈で型が決まるものは、そうは言えども一度決まっちゃったらずっとその型として扱われるのか。面白いー。

AntioneAntione2007/07/02 05:07http://64fdebd2c057be50b9c19d9a1e08d879-t.xxpogy.org <a href="http://64fdebd2c057be50b9c19d9a1e08d879-h.xxpogy.org">64fdebd2c057be50b9c19d9a1e08d879</a> [url]http://64fdebd2c057be50b9c19d9a1e08d879-b1.xxpogy.org[/url] [url=http://64fdebd2c057be50b9c19d9a1e08d879-b2.xxpogy.org]64fdebd2c057be50b9c19d9a1e08d879[/url] [u]http://64fdebd2c057be50b9c19d9a1e08d879-b3.xxpogy.org[/u] 9dc75301cfe28cfb0fb3d1863c1dee5e

2006-09-14忙しくてもHaskell

6.9 練習問題1 02:12

resolve f (x:xs) = (textify x) ++ (resolve f xs)
getenv key env = (fromMaybe "" $ (lookup key env))
readTemplate id = (readFile $ ((prefix repo) ++ "." ++ id))

答えを見てみると…

あら、$は外さないといけないのか。そっか、括弧をつける代わりに$だったっけ。3つめは、リストの連結に関しては暗黙で左側から評価されるという解釈かと思って明示しなかっただけ…という言い訳。でも解析される順番は大体思ったとおりみたいだ。

gnnnhpxdyodgnnnhpxdyod2012/12/21 21:22xZaaDo , [url=http://tpehygmvshbd.com/]tpehygmvshbd[/url], [link=http://eytpvdtuixqt.com/]eytpvdtuixqt[/link], http://vvkhvmoxziou.com/

tibwvnftibwvnf2012/12/23 06:29Qa3StF , [url=http://zqxxddondceh.com/]zqxxddondceh[/url], [link=http://reknozkvgglr.com/]reknozkvgglr[/link], http://tunnqdtpmazc.com/

2006-09-12Preluedeってステキな名前

4.4 練習問題1 02:27

標準入力を行単位ソート」の意味をどう捉えるのが一般的か。


1. 1行を1要素とみなして、複数行をソート

2. 1行の中に含まれる各文字列を1要素とみなしてソート


日本語の難しさは置いておいて、両方作ってみる。

1. 1行を1要素とみなして、複数行をソート

import List

main = do   cs <- getContents
            putStr $ unlines $ sort $ lines cs
> sort < sort.hs

            putStr $ unlines $ sort $ lines cs
import List
main = do   cs <- getContents

空行のみが先頭、スペースから始まるのが2番目、以下アルファベット順。

2. 1行の中に含まれる各文字を1要素とみなしてソート

import List

main = do   cs <- getContents
            putStr $ unlines $ map sort $ lines cs

> sort2 < sort2.hs
 Liimoprstt

       -<=Cacdeegimnnnoossttt
                    $$$Saceeiillmnnnopprrsssstttuu

各行中の要素がソートされております。

で、答えを見たら1.だった。でも$で繋がないで、.で繋いでるのは何でだ…。「=<< getContents」も意味はわかるけど、こんな書き方できるのは知らない。


4.4 練習問題2 02:40

import List

main = do   cs <- getContents
            putStr $ unlines $ map head $ group $ lines cs

text.txt

111
111
222
333
333
2222
>uniq < text.txt
111
222
333
2222

感想 02:40

  • わかんなくなりそうになったら後ろから順を追って考える
  • でもそれって関数型プログラミングなのかな?単に後ろから評価しているに過ぎないような。
  • 日本語って難しい

JayJay2012/12/22 21:57Touchdown! That's a really cool way of putintg it!

aubsczrzzyaubsczrzzy2012/12/23 11:512HuYSu <a href="http://qtjminqlxjyt.com/">qtjminqlxjyt</a>

rzfsrpnfibrzfsrpnfib2012/12/23 16:30sIj6DJ , [url=http://cirazwpffaen.com/]cirazwpffaen[/url], [link=http://tbymkkilzpce.com/]tbymkkilzpce[/link], http://jzmqrkaphlal.com/

ccdijlccdijl2012/12/26 07:28zgsmp4 , [url=http://qojvefeflayn.com/]qojvefeflayn[/url], [link=http://kuwdhxkjfhee.com/]kuwdhxkjfhee[/link], http://voeavzmjvjwv.com/

2006-09-10第3章

3.6 練習問題 00:59

main = do   cs <- getContents
            putStr $ concat $ map swapa cs

swapa 'a' = ['A']
swapa 'A' = ['a']
swapa c = [c]
>swapa < swapa.hs
mAin = do   cs <- getContents
            putStr $ concAt $ mAp swApA cs

swApA 'A' = ['a']
swApA 'a' = ['A']
swApA c = [c]

できたはできたけど、答えをみたらswapaの結果をわざわざリストで返す必要はないらしい。そっか、Char -> Charだから、

map swapa cs

の結果はCharリスト、すなわち文字列ってことか。

感想 00:59

JitendraJitendra2013/03/31 19:08You got to push it-this essenital info that is!

mtvaruskmtvarusk2013/04/01 18:43Deq8yX <a href="http://skhinelwwzmf.com/">skhinelwwzmf</a>

phohdkphohdk2013/04/02 08:00ubDOK6 <a href="http://eztuvogqcylk.com/">eztuvogqcylk</a>

atvombgxmvhatvombgxmvh2013/04/04 19:36JlTRKD , [url=http://jnsvmvqssnqo.com/]jnsvmvqssnqo[/url], [link=http://bkmypnftmjxj.com/]bkmypnftmjxj[/link], http://voeqapkvfjqy.com/