Just!!

Filed in Haskell Leave a comment

あいかわらず、すごいHaskellを読んで寝ています。
家に帰るとヨメとゲームやっちゃうし仕事中にHaskell遊びするわけにもいかんしで、本読んでばかりで手を動かしていません。だから実感なくて寝るんじゃないかバカなの。

いまだにHaskellの構文を見てピンとくるシーンが少ないです。あたしの脳がHaskellの文をパターンマッチングできてないんだわ。x:xsを認識するのがあたしの限界か?

今日はJustで遊んでみます。
Maybe a型という、なんかもういきなり「ハァ?」と思わずにいられないネーミングのそれですが、

*Main> :t Just 1
Just 1 :: Num a => Maybe a

*Main> :t Just 'A'
Just 'A' :: Maybe Char

*Main> :t Just "Abc"
Just "Abc" :: Maybe [Char]

*Main> :t Just []
Just [] :: Maybe [a]

*Main> :t Just [1]
Just [1] :: Num t => Maybe [t]

いたずらを思いついた。

*Main> :t Just Nothing
Just Nothing :: Maybe (Maybe a)

ほー。
こんだけかと言われそうですが、何かと勝手に制約を課しがちな、固いあたしの脳みそにとってはわりと快挙というか金星というか、ほめてあげたい感じ。えらいぞあたしの脳。

*Main> :t Just Just 1
:1:1:
    The function `Just' is applied to two arguments,
    but its type `a0 -> Maybe a0' has only one
    In the expression: Just Just 1

ダメだろうなとは思ったんだけど。

*Main> :t Just $  Just 1
Just $  Just 1 :: Num a => Maybe (Maybe a)

こうですね。

わからんとこだらけだけど読み進めよう、と思って読み進めると、次々にわからんことになって後戻り。
学ぶと難しいが使えば簡単、といったことをtnomura9さんも仰っていたので、まあまずは黙って手を動かせよってことですよね。

リスト操作に親しむ

Filed in Haskell 1 Comment

たしかPythonを使い始めてその良さが染み込み始めた頃、「リスト(っぽいいろんな型)の多彩さ」と「操作のシンプルさ」が気に入ったんだった。コードのスッキリした見た目も。
それまでのあたしは、配列と言ったら配列一種類であって、タプルとか辞書とか、なんのこっちゃだった。そんなのphpは一個の「配列」でおなじことやるよ?なんで分けてるの?って。
最初は楔形文字かと思っていたPythonのリスト内包表記なんかがだんだん読めるようになってきて、次第にphpで核プログラムのあちこちで、
リスト内包表記ができたら楽なのに
ここで関数を渡せたら楽なのに(仕事で使うphpは最新とは限りませんね!)
なんて思ったものでありました。

そういった視角からの目で見ますと、Haskellのいいところもやはり、リスト操作のシンプルさにあるのではないかと思えてきます。
Lispを学ぼうと思っていた頃は気持ち悪い概念だったcarとcdrも、こっちだとheadとtailですか、良い感じに慣れてきました。たぶんカーとかクダーとか、なにもイメージ出来ない奇妙な音で表現しているセンスに引いたんだと思います。「cdddr」とかああいうの。引くでしょ。
あれから年月は経ち、x:xsと書かれるだけで怒りゲージが上昇を始めていた当時のあたしはいません。
慣れるんだろうけど!慣れるんだろうけど!って連呼しながら腹を立てていた当時のあたしが非常に滑稽ではありますが、そういうみっともない足跡もブログに記していくのであります。ほんとに慣れるとは思ってなかった。
#昔話みたいに言ってますけど数週間前の話です

連長圧縮のとこでspanという関数が出てきていました。

Prelude> :t span
span :: (a -> Bool) -> [a] -> ([a], [a])
Prelude> span (<3) [1..10]
([1,2],[3,4,5,6,7,8,9,10])

ちょうど反対の概念であるところのbreakというのもあると。

Prelude> break (<3) [1..10]
([],[1,2,3,4,5,6,7,8,9,10])
Prelude> break (>3) [1..10]
([1,2,3],[4,5,6,7,8,9,10])

filterって関数もあったよねえ。これ便利だなーと実感している関数の一つ。

Prelude> filter (<3) [1..10]
[1,2]

Prelude> filter (>3) [1..10]
[4,5,6,7,8,9,10]
関数名 関数 リスト

の形式にみんな沿っていて、読みやすい。たぶんこれは慣れのせいで、(*2)を関数と認識できるようになった、というのが大きい。脳とは柔軟なものなんだな。

Prelude> span (=='A') $ init buff
("AA","BBCC")
Prelude> span (=='A') $ tail buff
("A","BBCCC")
Prelude> span (== head buff ) $ tail buff
("A","BBCCC")
Prelude> span (== head buff) $ tail buff
("A","BBCCC")
Prelude> break (== head buff) $ tail buff
("","ABBCCC")
Prelude> filter (== head buff) $ tail buff
"A"
Prelude> filter (/= head buff) $ tail buff
"BBCCC"

日々触るということが大事なのであります。

連長圧縮

Filed in Haskell 1 Comment

孤独のHaskellという記事があった。

遅刻して現場に付いたらRLEしてみようという例題(“AABBCCC”を”A2B2C3″にする関数を書こう)をやっていて

画像フォーマットのgifとかこういう圧縮やってんだよね。仕組みはよく知らないけど、AABBCCC→A2B2C3くらいならやれそうじゃん?
甘かった。

連長圧縮はともかく文字列の分割を考える

文字列をx:y:xsとかで取り出してx==yのとき云々とか考えてたけどなかなかうまく行かず、あちこちをさまよっている間に、groupという関数の存在を知ります。

Prelude> import Data.List
Prelude Data.List> group "aabbccc"
["aa","bb","ccc"]

ほー。これは便利だ。あたしこういう関数の存在も知らないままトライしようとしてるわけか。無謀だなあ。
で、これの仕掛けはどうなってんの?
たしかHoogleというサイトが便利だったはず。

Data.List.group

group
Data.Listの中に収録されてる。
実装も見られるみたいなので恐る恐る見てみる。こええ。

group                   :: Eq a => [a] -> [[a]]
group                   =  groupBy (==)

短い!! groupByに(==)を与えた、えーと部分適用?の状態なんだな。
group “aabbccc”

groupBy (==) “aabbccc”
はおなじなんだということな?

*Main Data.List> group "aabbccc"
["aa","bb","ccc"]
*Main Data.List> groupBy (==) "aabbccc"
["aa","bb","ccc"]

ははーなるほど。

Data.List.groupBy

「special case of groupBy」とのことなので、次はgroupByを見てみる

groupBy                 :: (a -> a -> Bool) -> [a] -> [[a]]
groupBy _  []           =  []
groupBy eq (x:xs)       =  (x:ys) : groupBy eq zs
                           where (ys,zs) = span (eq x) xs

書いてあることはわからんながら、たった数行で表現しちゃうものなのね。根拠無く、もっと長大な何かをイメージしてた。

効果的な切り取り方をしてると感じたのは

groupBy eq (x:xs)       =  (x:ys) : groupBy eq zs
                           where (ys,zs) = span (eq x) xs

ここ。
spanの第一引数に1文字目と等しいか比較する関数(eq x)を食わせ、第二引数に1文字目いがいの文字列(ABBCCC)を食わす。
返り値はパターンマッチングでリストysとリストzsとして受け取る。スマートだなあ。

span

循環参照的泉鏡花的らせんに迷いこむような錯覚を覚え始めましたが、こんどはspanというのを見てみよう。その前に使ってみよう。

*Main Data.List> :t span
span :: (a -> Bool) -> [a] -> ([a], [a])

なんかこういう型宣言をすぐ取ってこれるのは便利なんだなと思えるようになってきた。
真偽値を返す関数とリストの何かを渡すと、タプルにふたつのリストを内包したブツを返す。
左様で。

*Main Data.List> span (==1) [1,2,3]
([1],[2,3])
*Main Data.List> span (==1) [5,1,2,3]
([],[5,1,2,3])
*Main Data.List> span (==2) [5,1,2,3]
([],[5,1,2,3])
*Main Data.List> span (==2) [1,2,3]
([],[1,2,3])
*Main Data.List> span (==2) [2,3]
([2],[3])
*Main Data.List> span (==2) [2,2,2,3]
([2,2,2],[3])

狙った値で切り取れるんだコレ。便利だなー!
“AABBCCC”の”A”で”ABBCCC”をspanするわけだな!

*Main Data.List> span (=='A') "ABBCCC"
("A","BBCCC")

はいはいはいはい。

#以下長くなったので畳みます

Continue Reading

Haskellとは

Filed in Haskell Leave a comment

そもそものきっかけが「なんとなくカッコいい気がする」程度で歩きだしているのでどうでもいいことというか、何に役立てるつもりで勉強しているかという意識が希薄なんですが、そもそもHaskellって何なのかが気になったので、いつもどおりWikipediaさんに聞きました

Haskell は高階関数や静的多相型付け、定義可能な演算子、例外処理といった多くの言語で採用されている現代的な機能に加え、パターンマッチングやカリー化、リスト内包表記、ガードといった多くの特徴的な機能を持っている。また、遅延評価や再帰的な関数や代数的データ型もサポートしているほか、独自の概念として圏論のアイデアを利用し参照透過性を壊すことなく副作用のある操作(例えば 代入、入出力、配列など)を実現するモナドを含む。このような機能の組み合わせにより、手続き型プログラミング言語では記述が複雑になる関数でも Haskell ではたいていは実装が容易になる。

落語の演目にでも出てくるセリフか何かかねこれは。寿限無寿限無。
なにを指している文章なのかさっぱり、かけらも、理解できない。
「パターンマッチングやカリー化、リスト内包表記」というところだけ読めた。
圏論ってなんだろうということで調べてみると、さらにわけの分からない世界が広がっていた。なんだあれは。圏手とか射とか、何語だ。
こういう、途方もなく自分に縁遠い概念を勉強しようと思う時、どこから手を付けたらスタートできるんだろうか。
集合論とかがそうなのかなーと思って竹内なんとかさんの本も読んでるんだけど、やっぱり普通に使われてる言葉が既に意味不明で、
「あたしはこの本を読んでいいレベルに達していない」
ということをことごとく痛感させられているわけであります。

大人はたしかに当時、勉強しとけばよかったって言うよって言ってたが、ありゃホントだなあ。困ったなあ。

だれかが言ってたことですけど、Haskellを一言で言うと、Hello Worldを出力するまでに解説書の160ページを費やす言語であるというような一言を見かけました。
うん、他の言語だと一瞬で済むようなことに思うのに、遠いよね。
「純粋」な世界って大変なんだなあ。

andであるとかorであるとか

Filed in Haskell 1 Comment

すごいHaskellを読み続ける毎日。

身長と体重の数字を与えると、BMIをご丁寧に計算した上、お前は骨皮だのデブだのと罵倒する、いかにもHaskell(イメージ)なサンプルプログラムが掲載されていたので書いてみます。

bmiTell :: Double -> Double -> String
bmiTell weight height
        | bmi <= 18.5 = show bmi ++ " yase"
        | bmi <= 25.0 = show bmi ++ " hutu-"
        | bmi <= 30.0 = show bmi ++ " debu"
        | otherwise   = show bmi ++ " very debu"
        where bmi = weight / height ^ 2

返されるコメント部分は、ホントはもっと長い。長いコメント返すのが目的じゃないのでdebuとかにしました。
あたしは今のとこBMI23くらいなので(痩せました!)、あんま酷い罵倒はされません。よかったです。

で、この書き方がパターンマッチングと双璧をなす、かどうかはわからないが、関数の定義の際に便利な書き方であるということを覚えました。
switch文みたいだ。
個人的には、where以下で定義できる、変数やら関数やらの周辺に違和感を感じます。なんで後ろに並べるのか。手前の数行で使われる変数について知りたいときに、末尾を目で追わないといけないというのは不便な気がするんだけどなあ。
なんとなく、動作の内容が重要なのであって、値は二の次なんだよという姿勢の一環なのかなという感触。

文句はともかく、こういうのは繰り返し書き取りすることでしか身につかないので、手元で色々くだらないアレコレを書くことにします。

ohoho :: (Num a, Num a1) => a -> a1 -> [Char]
ohoho x y
      | x == 1 && y == 1 = "1 1"
      | x == 1 && y /= 1 = "1 ?"
      | x /= 1 && y == 1 = "? 1"
      | otherwise        = "Boo"

意味も中身もマトモにないけど書き取りの練習だからコレ。
で、ふと思う。
こういう、True and TrueはTrueでTrue or FalseはFalseですみたいなのはどう書いてるんだ実際。演算子あんのか。

*Main> 1 & 1
:1:3: Not in scope: `&'

*Main> 1 `&` 1
:1:4: parse error on input `&'

*Main> (&) 1 0
:1:1: Not in scope: `&'

ない。困りますそういうのは。
いやあるだろ。ないといろいろ無理だろう。探します。
「haskell 演算子」でぐぐりますと見つかったページが神がかっており、そこの一覧を眺めますと、ありました。
Haskellの演算子について纏めてみた@開発やプログラミングや家族や思考
すごい。

Bool

&じゃなくて&&だった。

Bool (&&) 論理積
Bool (||) 論理和

とあるので、さっそくやってみる。

*Main> (&&) 1 0
:1:8:
    No instance for (Num Bool)
      arising from the literal `0'
    Possible fix: add an instance declaration for (Num Bool)
    In the second argument of `(&&)', namely `0'
    In the expression: (&&) 1 0
    In an equation for `it': it = (&&) 1 0

おい。んー、表に「Bool」ってある。
あー。

*Main> (&&) True False
False

真偽値じゃないもん放り込んでんじゃねえよデブって言われてたんですね。デブじゃないし。BMI23だし。

Bits

当該ページの下の方に、似たようなのがあります。

Bits (.&.) ビットAND
Bits (.|.) ビットOR

びっと。ためしにやってみる。

Prelude> (.&.) 1 0
:1:1: Not in scope: `.&.'

Prelude> (.&.) True False
:1:1: Not in scope: `.&.'

そもそもスコープにないって。そんな関数知らねえよってこと?え?
あたしはそのへんピンときちゃう。

*Main> import Bits
*Main Bits>

今日は天気が悪い(あたしにとってはいい天気)なのでザジテン飲んでないんだ。頭冴えてます。

*Main Bits> (.&.) True False
:1:1:
    No instance for (Bits Bool)
      arising from a use of `.&.'
    Possible fix: add an instance declaration for (Bits Bool)
    In the expression: (.&.) True False
    In an equation for `it': it = (.&.) True False

*Main Bits> (.&.) 1 0
0

こっちは、真偽値じゃなくて01を受け取るのか。
冴えてもこの程度ですがあたしは生きています。

さらにピン

*Main> 1 `and` 1
:1:1:
    The operator `and' takes two arguments,
    but its type `[Bool] -> Bool' has only one
    In the expression: 1 `and` 1
    In an equation for `it': it = 1 `and` 1

だめか。だめとおもいきや、ちょっとエラーメッセージがちがう。
なんだ?

*Main> and True False
*Main> True and  False
*Main> 1 and 1
*Main> 1 and 0
*Main> 1 `and` 0
*Main> [1] `and` [0]
*Main> [True] `and` [False]

などと盲滅法に打ちまくり怒られまくったあとで、ようやっと
「but its type `[Bool] -> Bool' has only one」
とあるのに気づきます。なんでリストなのん……?

*Main> and [False]
False
*Main> and [True]
True

意味がわからない。役に立つのかコレ。
さらにピン。

*Main> and [True, False]
False
*Main> and [True, True]
True

こうだな。

*Main> and [True, True, False]
False

*Main> and [ 1, 1, 0]
:1:13:
    No instance for (Num Bool)
      arising from the literal `0'
    Possible fix: add an instance declaration for (Num Bool)
    In the expression: 0
    In the first argument of `and', namely `[1, 1, 0]'
    In the expression: and [1, 1, 0]

意図がわかった。なるほどー。なるほどねー。

Haskellのクラスはちがう

Filed in Haskell Leave a comment

本の何処かに「Haskellのクラスは、JavaやPythonのクラスとは違う概念だから!Pythonとかのクラスのことはきれいに忘れてほしいな!」とか書いてある。
違う概念なんだったら違う言葉で表現していてほしい。Haskellのver1.0が世に出たのは1990年だというから、そのころならまだ、クラスを別の呼び方にするには間に合ったんじゃないのか。なんなのか。
いまだに用語のアレコレが染み付いておらず、電車の中で読むたびに寝ています。
という愚痴。

いつか学習しているうちにたどり着いて見つけるのかもしれないが、とあるオブジェクトのかたちと振舞いを定義した塊としてのクラス、Pythonやphpで言うところのクラスのような定義の仕方についての記述がなかなか出てこないことが、不安として横たわっています。
既知の「クラス」をモジュールとかのあたりのファイルを単位とした何かで担うのであろうか。
いちいち置き換えて考えようとするのは悪手なんだろうとは思うんだけど、漠然とわからないまま彷徨うあまり、手がかりを探してしまう感じ。

データ型を定義するの辺り

Filed in Haskell Leave a comment

すごkellp112の「形づくる」のあたり。
#ページ進んだとおもいきや戻ってという読み方をしているので一向に進みません。

テキスト読みながらぼんやり書いてぼんやり動かして、数日うまくいかないことがありました。
さっき解決したのでメモ。

円と矩形の定義をして、面積を得る関数を書きましょうみたいなあたり。

data Shape = Circle Float Float Float |
             Square Float Float Float Float 
     deriving (Show, Read)

area (Circle _ _ r  ) = pi * r ^ 2
area (Square _ _ w h) = w * h

piは予約語なんだな。
こう書いて、

*Main> area $ Circle 10 10 10
314.15927

うん。

*Main> area $ Square 10 10 10 10
*** Exception: shape.hs:5:1-39: Non-exhaustive patterns in function area

えー。
dataの宣言のところの改行が良くないのだろうかとか、インデントの位置だろうかとか、そらもういろいろ試したがここから数日間動けず、イライラしておりました。
Circleの面積は得られる。
Squareは得られない。Squareが予約語なのかも!とかで書き換えてみてもダメで、ああそうだ、なんか型の宣言を書いといたほうがいいみたいな話だったなあと思い、

data Shape = Circle Float Float Float |
             Square Float Float Float Float 
     deriving (Show, Read)

area :: Shape -> Float
area (Circle _ _ r  ) = pi * r ^ 2
area (Square _ _ w h) = w * h

1行書き足し。
これがじつは正解で、

*Main> area $ Square 10 10 10 10
100.0

うごいた。
本には「型宣言を書いておくことはよい習慣です」くらいの書き方してたけど、違うじゃん。
必須じゃん。

続・身についてないっぽいポイント

Filed in Haskell Leave a comment

先日の記事で、

(\x y -> x + y)

これが何してんのかすぐに読めない。
どうも関数\xと引数yって読んでしまい、思考が脱輪するのね。

Prelude> :t ($)
($) :: (a -> b) -> a -> b

こういうのを、(a->b)は関数で、引数がaで、bがreturnされる、と読めない。
a -> (a -> b) -> bって書いてくれればいいのに。

と書いた。

a -> (a -> b) -> bって書いてくれればいいのに。

これ中置き関数じゃないか。a `mod` bじゃないか。
で、a `mod` bはもともとは(mod) a bなんだから、結局

($) :: (a -> b) -> a -> b

の形に戻ってくるんだわな。
自分の視覚にとっての読みやすさの問題なんだなー純粋に。

中国の剰余定理

Filed in Haskell Leave a comment

逆ポーランド記法の電卓があるらしいと知り、hpの10,000円くらいの高機能電卓、それもなぜかグラフ表示までできるようなやつをみてびっくり、amazonのレビューも筋金入りの数学オジサマがたの巣窟となっている感があり、いやはや世の中にはいろんな世界があるものだと逃げ帰ってきた次第です。
で、hp 50g ハイエンド グラフ電卓という電卓のレビューで、

しかしながら2300を超えるといわれる関数には、整数a, b, cを与えてau + bv = cを満たす整数u, vを計算するIACUVという関数や、中国の剰余定理の解を求めるICHINREMやCHINREMなど数学の専門家でもなければなかなかお目にかかることのないものまで含まれています。

この電卓にはいっぱい関数が入ってるらしい。
そ、そうですか。
言われてみれば普通の√とかもあれ、関数か。どころか、加減乗除ぜんぶ関数だ。それのもっといろんなことができるのが関数電卓だということなんだな。
あたしがこの電卓を買っても全然アレなので買うつもりはないけど、
中国の余剰定理
という一文に目が止まりました。なにこれ。なんだかマイナーな関数の搭載がされているという話ですが、そういう定理があるのね。
んでWikipediaの「中国の剰余定理」を見てみる事にしました。

『孫子算経』には、「3で割ると2余り、5で割ると3余り、7で割ると2余る数は何か」という問題とその解法が書かれている。中国の剰余定理は、この問題を他の整数についても適用できるように一般化したものである。

あら、シンプルな話。これならあたしにも何とかできそう。
#孫子算経というのは中国の古い書物で、数学や暗号について書かれたものだそうです。

解いてみる

三種類の数で割った剰余がそれぞれtrueだったらナンチャラ、というのを書けばいいんだろう。
[1..]とかで順番に洗っていけばいいんだわな。
[1..]だと終わりがないからいかんな。さしあたり[1..100]とかにしとこう。見つからなかったら1000とか10000とか数字を上げていけばよろしい。
#ちなみに、うっかり見ちゃったので、上の条件を満たすのは最小で23だということまでは把握しています。ちぇ。

こんなかんじ?

Prelude> let foo x = (x `mod` 3 == 2, x `mod` 5 == 3,x `mod` 7 ==2 )

さっそくためします。

Prelude> foo 23
(True,True,True)
Prelude> foo 22
(False,False,False)
Prelude> foo 8
(True,True,False)

うん。んー、うん。

Prelude> :t foo
foo :: Integral a => a -> (Bool, Bool, Bool)

タプルで返ってくるのは不便だ。ぜんぶ満たしてたらTrueでいいんだけど。

Prelude> let foo x = (x `mod` 3 == 2 && x `mod` 5 == 3 && x `mod` 7 ==2 )
Prelude> :t foo
foo :: Integral a => a -> Bool

どうかな。

Prelude> foo 23
True
Prelude> foo 22
False
Prelude> foo 8
False

書き方あってたみたい。で、リストの中から条件に合うものを拾うのはfilterだということなので、

Prelude> :t filter
filter :: (a -> Bool) -> [a] -> [a]

Boolが返る関数とリストを渡すのね。

Prelude> filter foo [1..100]
[23]

お。

Prelude> filter foo [1..1000]
[23,128,233,338,443,548,653,758,863,968]

おお。
実に大したことはないんですが、嬉しい。
少なくともいまのうちは、htmlだcgiだバッチだと吠えるよりは、こういう算数あそびに使ってるほうがいいのかも。

そーいえば

takeで先頭n個の取得ができるんだった。

Prelude> take 1 filter foo [1..1000]

:1:1:
    The function `take' is applied to four arguments,
    but its type `Int -> [a0] -> [a0]' has only two
    In the expression: take 1 filter foo [1 .. 1000]
    In an equation for `it': it = take 1 filter foo [1 .. 1000]

あちゃー。
そうか、このままだと take 1 で拾おうとするリストが”filter”になっちゃうんだ。
$つけよう。

Prelude> take 1 $ filter foo [1..1000]
[23]
Prelude> take 1 $ filter foo [1..]
[23]

これなら[1..1000]じゃなくて、[1..]でいいんだな。Lazyはよい。
少し賢くなった気分。

リストのスライス

Filed in Haskell Leave a comment

Prelude> [1..5]
[1,2,3,4,5]

こんなリストさんで試す。
先頭n個を取りたいときはtakeを使うとあった。

Prelude> take 3 [1..5]
[1,2,3]

うん。わかる。

Prelude> 1:2:3:4:5:[]
[1,2,3,4,5]

これもおなじことなので、

Prelude> take 3 1:2:3:4:5:[]

:1:16:
    No instance for (Num [a0])
      arising from the literal `5'
    Possible fix: add an instance declaration for (Num [a0])
    In the first argument of `(:)', namely `5'
    In the second argument of `(:)', namely `5 : []'
    In the second argument of `(:)', namely `4 : 5 : []'

あるぇー?おなじじゃない模様。なんなの?
もしかして、と思い、遅延評価?だかをするみたいな風情の$を使ってみる。

Prelude> take 3 $ 1:2:3:4:5:[]
[1,2,3]

はーなるほどー。
で、

Prelude> take 3 [1..5]
[1,2,3]

先ほどこれはできたわけだがこっちはどうかなと試すと、

Prelude> take 3 $ [1..5]
[1,2,3]

同じなんだ。$は「右端まであるカッコ」だという記述があったので、つまりそれは、

Prelude> take 3 ([1..5])
[1,2,3]

はーなるほど。
さっきのエラー文言そのものをみてみる。おかしいと言っているのは16桁目、「5」のあたり。
「リテラル「5」から発生するための(Num[a0])インスタンスはありません。」
エキサイト様すいません、わかんないっす。

Possible fix: add an instance declaration for (Num [a0])

こっちは修正すべき箇所の指示かな。
「実例宣言を加える、のために(Num[a0])」
インスタンスの宣言を加えろ?Num [a0]ってのがよくわからない。
リストを処理しようとしたけど、数値リテラルだったからやーめた、という解釈をしてみます。

take 3する時点では、1:2:3:4:5:[]は1から5のリテラルと空リストの連なった何かであってそれはリストじゃないんだよと言われているのでしょうか。
で、

(1:2:3:4:5:[])

と書いたことで

[1,2,3,4,5]

に置き換わって、先頭3つをスライスできるようになりました、めでたし的なかんじ?

Prelude> 1:2:3:4:5:[] == [1..5]
True

うーん、よくわからない。わからんが、take 3さんに1:2:3:4:5:[]を渡しても駄目であるということは分かった。
それを分かったというのかというと、ちょっと微妙な気はしますが。

TOP