<jupyter_start><jupyter_text>メモLearn You a Haskell for Great Good! by <NAME> を jupyter notebook にしてくれた人がいる。これを colab 化する。https://github.com/jamesdbrock/learn-you-a-haskell-notebook/tree/master/notebookいまここ  https://colab.research.google.com/github/jamesdbrock/learn-you-a-haskell-notebook/blob/master/notebook/02-starting-out.ipynb<jupyter_code># 準備
%%capture
!apt install haskell-platform
!ghc -e 'putStrLn "hello world!"'
# ファイルを作る
%%writefile hello.hs
main = putStrLn "hello, world"
!runghc hello.hs
%%html
<table border="1">
<thead>
<tr><th>キーボードショートカット </th><th> 作  用 </th></tr>
</thead>
<tbody>
<tr><td>Shift+Enter </td><td> 実行して次のセルに移る </td></tr>
<tr><td>Ctrl+Enter </td><td> 実行してそのセルに留まる </td></tr>
<tr><td>Alt+Enter </td><td> 実行して次に新しいセルを作って移る </td></tr>
<tr><td>Enter </td><td> セルを編集する </td></tr>
<tr><td>Ctrl+Shift+Enter </td><td> 選択範囲を全て実行する </td></tr>
<tr><td>Ctrl+Shift+- </td><td> カーサーポジションでセルを分割する</td></tr>
</tbody>
</table><jupyter_output><empty_output><jupyter_text>Here's some simple arithmetic.<jupyter_code>!ghc -e '2 + 15'
!ghc -e '49 * 100'
!ghc -e '1892 - 1472'
!ghc -e '5 / 2' #=> 2.5 になる
!ghc -e '(50 * 100) - 4999'
!ghc -e '50 * 100 - 4999'
!ghc -e '50 * (100 - 4999)'
# 次のコードはエラーになる
# マイナス符号がついた数値は括弧で囲む必要がある
%%script false
!ghc -e '5 * -3'
!ghc -e '3 == 4' #=> False と出力される
!ghc -e 'True || False' #=> True
!ghc -e 'False && False' #=> False
!ghc -e 'True' #=> True
%%script False
!ghc -e 'true' #=> error Variable not in scope: true
!ghc -e 'not False'
!ghc -e 'not (True && True)'
!ghc -e '5 == 5'
!ghc -e '1 == 0'
!ghc -e '5 /= 5' #=> False `/=` は not equal の意味
!ghc -e '5 /= 4'
!ghc -e '"hello" == "hello"'
# 次のコードはエラーになる
# %%script false の行を消して実行してエラーを確認すること
%%script false
!ghc -e '5 + "llama"'
# 文字列の連結は `++` を用いる
!ghc -e '"5" ++ "llama"' #=> 5llama
# Haskell のエラーは比較的親切
# `+` は両辺の引数が number でなければならない
# `==` は両辺のデータの型が同じで比較可能なこと
# 5 + 4.0 の場合は整数と浮動小数点数の足し算で浮動小数点数になる
# `*` のように数字と数字の間に置かれて作用する関数を中置関数 infix function と呼ぶ
# 他の殆どの関数は前置 prefix function である
# Haskell では前置関数の後にスペースを入れて引数を書く。括弧は要らない
# succ 関数は順序の定義された型を引数に取り次に来る値を返す
!ghc -e 'succ 8'
!ghc -e 'pred 8'
# min , max 関数は引数をそれぞれ 2つ取る
!ghc -e 'min 9 10'
!ghc -e 'min 3.4 3.2'
!ghc -e 'max 100 101'
# 関数の優先順位が最も高い
!ghc -e 'succ 9 + max 5 4 + 1' #=> 16
!ghc -e '(succ 9) + (max 5 4) + 1' #=>16
!echo
!ghc -e 'succ 9 * 10' #=> 100
!ghc -e 'succ (9 * 10)' #=>  91
# 前置関数を中置関数として使うとわかりやすい
# 前置関数を中置関数として使う方法 => バッククオートで囲む
!ghc -e 'div 92 10' #=> 9
!ghc -e '92 `div` 10' #=> 9
# Haskell で `bar (bar 3)` は括弧が必須の言語で言えば `bar(bar(3))` に当たることを理解すること
# 関数の作り方
# 関数名と変数と `=` とその後に定義を書く
!ghc -e 'doubleMe x = x + x'
# コマンドラインワンライナーで Haskell で関数定義して使う
# 次のようには書けない
# !ghc -e 'doubleMe x = x + x; doubleMe 9'
# `let in` を使う
!ghc -e 'let doubleMe x = x + x in doubleMe 9' #=> 18
# 引数を 2つ取る関数
!ghc -e 'doubleUs x y = x*2 + y*2'
!ghc -e 'let doubleUs x y = x*2 + y*2 in doubleUs 4 9'
# 定義が複数あるとき波括弧とセミコロンでまとめられる
# Haskellの関数は特定の順序である必要はないので、最初にdoubleMeを定義し、
# 次にdoubleUsを定義するか、その逆にするかは問題ではありません。
!ghc -e 'let {doubleUs x y = doubleMe x + doubleMe y; doubleMe x = x + x} in doubleUs 4 9'
# プログラムファイルを作って実行する
%%writefile temp.hs
main = 
  doubleMe x = x + x
  doubleUs x y = doubleMe x + doubleMe y 
  putStrLin doubleUs 28 88 + doubleMe 123'
# 実験 プログラムファイルを作って実行する
%%writefile temp.hs
doubleMe x = x + x
doubleUs x y = doubleMe x + doubleMe y 
main = 
  print $ doubleUs 28 88 + doubleMe 123
!runghc temp.hs #=> 56+176+246 
!ghc -e '56+176+246'
# 次に、数値に2を掛ける関数を作成しますが、100より大きい数値はそのままで十分な大きさであるため、
# その数値が100以下の場合に限ります。
%%script false
doubleSmallNumber x = if x > 100
                        then x
                        else x*2
!ghc -e 'let doubleSmallNumber x = if x > 100 then x else x*2 in doubleSmallNumber 42'
# Haskell の if ステートメントは、else部 分が必須である
# Haskell ではすべての式と関数が何かを返す必要があります
# Haskellの if ステートメントは式であり、常に何かを返します
# 前の関数で生成されたすべての数値に1を追加したい場合は、その本体をこのように書くことができます。
%%script false
doubleSmallNumber' x = (if x > 100 then x else x*2) + 1
!ghc -e "let doubleSmallNumber' x = (if x > 100 then x else x*2) + 1 in doubleSmallNumber' 42"
# このテキストではこのように関数をちょっと変更した時に関数名の末尾に
# アポストロフィ `'` をつけることにしている
# コマンドラインワンライナーにする際、通常文字列をワンクオート (= アポストロフィ)
# で囲むのでこれはトラブルの原因になるのでよろしくない
# functionname02 とかにする
# パラメーター なしの関数
%%writefile temp.hs
conanO'Brien = "It's a-me, Conan O'Brien!"
main =
  putStrLn conanO'Brien
!runghc temp.hs
# 上の関数はパラメーターをとらない例である
# 関数名は大文字で始めることが出来ない
# パラメーターを受け取らない関数は通常定義(名前)である、と言う
# Haskell は意味を変更出来ないため
# conanO'Brienと文字列「It'sa-me、ConanO'Brien！」 を互換的に使用できます
# しかし!!!! アポストロフィは面倒なので外してみる!!!!
!ghc -e 'let conanOBrien = "Its a-me, Conan OBrien!" in putStrLn conanOBrien'<jupyter_output>Its a-me, Conan OBrien!<jupyter_text>---リスト<jupyter_code># 連続した整数のリストは範囲を使って次のように書く
%%script false
[1..20]
!ghc -e '[1..20]'
!ghc -e "['a'..'z']"
!ghc -e "['K'..'Z']"
# 範囲にステップを指定する方法
!ghc -e '[2,4..20]'
!ghc -e '[3,6..20]'
# 等差数列にしか使えないみたい
# マイナスは出来る [20,19..1]
# 小数点の差はどうするのか #=> 使わない方が良い
!ghc -e '[0.1, 0.3 .. 1]'
# 無限リスト
# Haskell は lazy なので無限リストは使う時まで評価しない
# 例えば 13 の倍数のリストの最初の 24個が欲しいとする
# 範囲 range で上限を指定しないと無限リストになる
!ghc -e '[13,26 .. 13*24]'
!ghc -e 'take 24 [13,26 ..]'
# 無限リストを生成する関数
# cycle は与えられたリストを無限に繰り返す
!ghc -e 'take 10 (cycle [1,2,3])'
!ghc -e 'take 12 (cycle "LOL ")'
# repeat
!ghc -e 'take 10 (repeat 5)'
!ghc -e 'take 10 (repeat "LOL")'
# 単一要素の繰り返せは replicate の方が便利だろう
!ghc -e 'replicate 3 10'
!ghc -e 'replicate 3 "LOL"'<jupyter_output>[5,5,5,5,5,5,5,5,5,5]
["LOL","LOL","LOL","LOL","LOL","LOL","LOL","LOL","LOL","LOL"]
[10,10,10]
["LOL","LOL","LOL"]<jupyter_text>いまここ  $ S=\{2 \centerdot x | x \in \mathbb{N}, x \le 10 \}$<jupyter_code># 内包表記 list comprehension
# 数学で集合を習った時に次のような
あなたが今までに取ったことがあれば
数学のコースでは、おそらく*セットの理解*に遭遇したことがあります。
それらは通常、一般的なものからより具体的なセットを構築するために使用されます
セット。最初の10個を含むセットの基本的な理解
自然数は$S= \ {2 \ centerdot x | x \ in \ mathbb {N}、x \ le 10\}$。前の部分
パイプは出力関数と呼ばれ、 `x`は変数、`N`は
入力セットと`x<=10`が述語です。つまり、セット
述語を満たすすべての自然数の倍精度が含まれます。

Haskellでそれを書きたいのなら、`takeのようなことをすることができます
10 [2,4..]`。しかし、最初の10個のナチュラルの2倍が必要ない場合はどうなりますか
数字ですが、ある種のより複雑な関数がそれらに適用されていますか？我々は出来た
そのためにリスト内包を使用してください。リスト内包表記は非常に似ています
理解度を設定します。最初の10個の偶数を取得することに固執します
今のところ。使用できるリスト内包表記は`[x* 2 | x<-[1..10]]`。
`x`は`[1..10]`から引き出され、`[1..10]`のすべての要素に対して（
`x`にバインドされている場合、その要素を取得しますが、2倍になります。これが
実行中の理解。<jupyter_output><empty_output><jupyter_text>If you've ever taken acourse in mathematics, you've probably run into *set comprehensions*.They're normally used for building more specific sets out of generalsets. A basic comprehension for a set that contains the first ten evennatural numbers is $ S=\{2 \centerdot x | x \in \mathbb{N}, x \le 10 \}$  . The part beforethe pipe is called the output function, `x` is the variable, `N` is theinput set and `x <= 10` is the predicate. That means that the setcontains the doubles of all natural numbers that satisfy the predicate.If we wanted to write that in Haskell, we could do something like `take10 [2,4..]`. But what if we didn't want doubles of the first 10 naturalnumbers but some kind of more complex function applied on them? We coulduse a list comprehension for that. List comprehensions are very similarto set comprehensions. We'll stick to getting the first 10 even numbersfor now. The list comprehension we could use is `[x*2 | x <- [1..10]]`.`x` is drawn from `[1..10]` and for every element in `[1..10]` (which we havebound to `x`), we get that element, only doubled. Here's thatcomprehension in action.<jupyter_code>[x*2 | x <- [1..10]]<jupyter_output><empty_output><jupyter_text>As you can see, we get the desired results. Now let's add a condition(or a predicate) to that comprehension. Predicates go after the bindingparts and are separated from them by a comma. Let's say we want only theelements which, doubled, are greater than or equal to 12.<jupyter_code>[x*2 | x <- [1..10], x*2 >= 12]<jupyter_output><empty_output><jupyter_text>Cool, it works. How about if we wanted all numbers from 50 to 100 whoseremainder when divided with the number 7 is 3? Easy.<jupyter_code>[ x | x <- [50..100], x `mod` 7 == 3]<jupyter_output><empty_output><jupyter_text>Success! Note that weeding out lists by predicates is also called*filtering*. We took a list of numbers and we filtered them by thepredicate. Now for another example. Let's say we want a comprehensionthat replaces each odd number greater than 10 with `"BANG!"` and each oddnumber that's less than 10 with `"BOOM!"`. If a number isn't odd, we throwit out of our list. For convenience, we'll put that comprehension insidea function so we can easily reuse it.<jupyter_code>boomBangs xs = [ if x < 10 then "BOOM!" else "BANG!" | x <- xs, odd x]<jupyter_output><empty_output><jupyter_text>The last part of the comprehension is the predicate. The function [`odd`](https://hackage.haskell.org/package/base/docs/Prelude.htmlv:odd)returns [`True`](https://hackage.haskell.org/package/base/docs/Prelude.htmlv:True) on an odd number and [`False`](https://hackage.haskell.org/package/base/docs/Prelude.htmlv:False) on an even one. The element isincluded in the list only if all the predicates evaluate to [`True`](https://hackage.haskell.org/package/base/docs/Prelude.htmlv:True).<jupyter_code>boomBangs [7..13]<jupyter_output><empty_output><jupyter_text>We can include several predicates. If we wanted all numbers from 10 to20 that are not 13, 15 or 19, we'd do:<jupyter_code>[ x | x <- [10..20], x /= 13, x /= 15, x /= 19]<jupyter_output><empty_output><jupyter_text>Not only can we have multiple predicates in list comprehensions (anelement must satisfy all the predicates to be included in the resultinglist), we can also draw from several lists. When drawing from severallists, comprehensions produce all combinations of the given lists andthen join them by the output function we supply. A list produced by acomprehension that draws from two lists of length 4 will have a lengthof 16, provided we don't filter them. If we have two lists, `[2,5,10]` and`[8,10,11]` and we want to get the products of all the possiblecombinations between numbers in those lists, here's what we'd do.<jupyter_code>[ x*y | x <- [2,5,10], y <- [8,10,11]]<jupyter_output><empty_output><jupyter_text>As expected, the length of the new list is 9. What if we wanted allpossible products that are more than 50?<jupyter_code>[ x*y | x <- [2,5,10], y <- [8,10,11], x*y > 50]<jupyter_output><empty_output><jupyter_text>How about a list comprehension that combines a list of adjectives and alist of nouns … for epic hilarity.<jupyter_code>let nouns = ["hobo","frog","pope"]
let adjectives = ["lazy","grouchy","scheming"]
[adjective ++ " " ++ noun | adjective <- adjectives, noun <- nouns]<jupyter_output><empty_output><jupyter_text>I know! Let's write our own version of [`length`](https://hackage.haskell.org/package/base/docs/Prelude.htmlv:length)! We'll call it `length'`.<jupyter_code>length' xs = sum [1 | _ <- xs]<jupyter_output><empty_output><jupyter_text>`_` means that we don't care what we'll draw from the list anyway soinstead of writing a variable name that we'll never use, we just write`_`. This function replaces every element of a list with `1` and then sumsthat up. This means that the resulting sum will be the length of ourlist.Just a friendly reminder: because strings are lists, we can use listcomprehensions to process and produce strings. Here's a function thattakes a string and removes everything except uppercase letters from it.<jupyter_code>removeNonUppercase st = [ c | c <- st, c `elem` ['A'..'Z']]<jupyter_output><empty_output><jupyter_text>Testing it out:<jupyter_code>removeNonUppercase "Hahaha! Ahahaha!"
removeNonUppercase "IdontLIKEFROGS"<jupyter_output><empty_output><jupyter_text>The predicate here does all the work. It says that the character will beincluded in the new list only if it's an element of the list `['A'..'Z']`.Nested list comprehensions are also possible if you're operating onlists that contain lists. A list contains several lists of numbers.Let's remove all odd numbers without flattening the list.<jupyter_code>let xxs = [[1,3,5,2,3,1,2,4,5],[1,2,3,4,5,6,7,8,9],[1,2,4,2,1,6,3,1,3,2,3,6]]
[ [ x | x <- xs, even x ] | xs <- xxs]<jupyter_output><empty_output><jupyter_text>You can write list comprehensions across several lines. It's better to split longer list comprehensions across multiplelines, especially if they're nested.Tuples------In some ways, tuples are like lists — they are a way to store severalvalues into a single value. However, there are a few fundamentaldifferences. A list of numbers is a list of numbers. That's its type andit doesn't matter if it has only one number in it or an infinite amountof numbers. Tuples, however, are used when you know exactly how manyvalues you want to combine and its type depends on how many componentsit has and the types of the components. They are denoted withparentheses and their components are separated by commas.Another key difference is that they don't have to be homogenous. Unlikea list, a tuple can contain a combination of several types.Think about how we'd represent a two-dimensional vector in Haskell. Oneway would be to use a list. That would kind of work. So what if wewanted to put a couple of vectors in a list to represent points of ashape on a two-dimensional plane? We could do something like`[[1,2],[8,11],[4,5]]`. The problem with that method is that we could alsodo stuff like `[[1,2],[8,11,5],[4,5]]`, which Haskell has no problem withsince it's still a list of lists with numbers but it kind of doesn'tmake sense. But a tuple of size two (also called a pair) is its owntype, which means that a list can't have a couple of pairs in it andthen a triple (a tuple of size three), so let's use that instead.Instead of surrounding the vectors with square brackets, we useparentheses: `[(1,2),(8,11),(4,5)]`. What if we tried to make a shape like`[(1,2),(8,11,5),(4,5)]`? Well, we'd get this error:<jupyter_code>[(1,2),(8,11,5),(4,5)]<jupyter_output><empty_output><jupyter_text>It's telling us that we tried to use a pair and a triple in the samelist, which is not supposed to happen. You also couldn't make a listlike `[(1,2),("One",2)]` because the first element of the list is a pairof numbers and the second element is a pair consisting of a string and anumber. Tuples can also be used to represent a wide variety of data. Forinstance, if we wanted to represent someone's name and age in Haskell,we could use a triple: `("Christopher", "Walken", 55)`. As seen in thisexample, tuples can also contain lists.Use tuples when you know in advance how many components some piece ofdata should have. Tuples are much more rigid because each different sizeof tuple is its own type, so you can't write a general function toappend an element to a tuple — you'd have to write a function forappending to a pair, one function for appending to a triple, onefunction for appending to a 4-tuple, etc.While there are singleton lists, there's no such thing as a singletontuple. It doesn't really make much sense when you think about it. Asingleton tuple would just be the value it contains and as such wouldhave no benefit to us.Like lists, tuples can be compared with each other if their componentscan be compared. Only you can't compare two tuples of different sizes,whereas you can compare two lists of different sizes. Two usefulfunctions that operate on pairs:__[`fst`](https://hackage.haskell.org/package/base/docs/Prelude.htmlv:fst)__ takes a pair and returns its first component.<jupyter_code>fst (8,11)
fst ("Wow", False)<jupyter_output><empty_output><jupyter_text>__[`snd`](https://hackage.haskell.org/package/base/docs/Prelude.htmlv:snd)__ takes a pair and returns its second component. Surprise!<jupyter_code>snd (8,11)
snd ("Wow", False)<jupyter_output><empty_output><jupyter_text>> __Note:__ these functions operate only on pairs. They won't work on> triples, 4-tuples, 5-tuples, etc. We'll go over extracting data from> tuples in different ways a bit later.A cool function that produces a list of pairs: __[`zip`](https://hackage.haskell.org/package/base/docs/Prelude.htmlv:zip)__. It takes two listsand then zips them together into one list by joining the matchingelements into pairs. It's a really simple function but it has loads ofuses. It's especially useful for when you want to combine two lists in away or traverse two lists simultaneously. Here's a demonstration.<jupyter_code>zip [1,2,3,4,5] [5,5,5,5,5]
zip [1 .. 5] ["one", "two", "three", "four", "five"]<jupyter_output><empty_output><jupyter_text>It pairs up the elements and produces a new list. The first element goeswith the first, the second with the second, etc. Notice that becausepairs can have different types in them, [`zip`](https://hackage.haskell.org/package/base/docs/Prelude.htmlv:zip) can take two lists thatcontain different types and zip them up. What happens if the lengths ofthe lists don't match?<jupyter_code>zip [5,3,2,6,2,7,2,5,4,6,6] ["im","a","turtle"]<jupyter_output><empty_output><jupyter_text>The longer list simply gets cut off to match the length of the shorterone. Because Haskell is lazy, we can zip finite lists with infinitelists:<jupyter_code>zip [1..] ["apple", "orange", "cherry", "mango"]<jupyter_output><empty_output><jupyter_text>Here's a problem that combines tuples and list comprehensions: whichright triangle that has integers for all sides and all sides equal to orsmaller than 10 has a perimeter of 24? First, let's try generating alltriangles with sides equal to or smaller than 10:<jupyter_code>let triangles = [ (a,b,c) | c <- [1..10], b <- [1..10], a <- [1..10] ]<jupyter_output><empty_output><jupyter_text>We're just drawing from three lists and our output function is combiningthem into a triple. If you evaluate that by typing out `triangles` inGHC, you'll get a list of all possible triangles with sides under orequal to 10. Next, we'll add a condition that they all have to be righttriangles. We'll also modify this function by taking into considerationthat side b isn't larger than the hypotenuse and that side a isn'tlarger than side b.<jupyter_code>let rightTriangles = [ (a,b,c) | c <- [1..10], b <- [1..c], a <- [1..b], a^2 + b^2 == c^2]<jupyter_output><empty_output><jupyter_text>We're almost done. Now, we just modify the function by saying that wewant the ones where the perimeter is 24.<jupyter_code>let rightTriangles' = [ (a,b,c) | c <- [1..10], b <- [1..c], a <- [1..b], a^2 + b^2 == c^2, a+b+c == 24]
rightTriangles'<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.12324365537523145, 'fraction_numerical': 0.030334386232436554, 'mean_word_length': 4.975593882199805, 'pattern_counts': {'":': 0, '<': 181, '<?xml version=': 0, '>': 179, 'https://': 11, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '26', 'dir': 'jupyter-structured-clean-dedup', 'id': '63656', 'license': 'MIT', 'n_tokens_mistral': 8115, 'n_tokens_neox': 7380, 'n_words': 2302, 'path': 'haskell_lipovaca.ipynb', 'repo_name': 'kalz2q/myjupyternotebooks', 'size': '18370'}