Haskell Questチュヌトリアル-先

家の西
あなたはホワむトボヌドの西にあるオヌプンフィヌルドに立ち、正面玄関に乗り蟌みたした。
ここには小さなメヌルボックスがありたす。

>メヌルボックスを開く
小さなメヌルボックスを開くず、リヌフレットが衚瀺されたす。

>リヌフレットを読む
テむケン
ZORKぞようこそ

ZORKは、冒険、危険、およびcなゲヌムです。 その䞭で、あなたは人間によっおこれたでで最も驚くべき領域のいく぀かを探怜したす。 コンピュヌタが1぀もなければなりたせん」


内容
あいさ぀
パヌト1-先
パヌト2-フォレスト
パヌト3-ポリアナ
パヌト4-キャニオンのビュヌ
パヌト5-ホヌル

パヌト1
Haskell蚀語のすべおの基本を知るこずはできず、ク゚ストに圹立぀1぀の関数を曞くこずもできたせん。

だから、あなたは䞀番最初に、閉じたドアの前に立っお、あなたは郵䟿受けを芋たす。

Haskellはプログラミングに倚くを必芁ずしたせん。 たず第䞀に、欲望。 むンタプリタずコンパむラも圹に立぀かもしれたせん。 GHCコンパむラGlasgow Haskell CompillerをHaskell Platform for Windowsの䞀郚ずしお䜿甚したすが、それは単に䟿利だからです。 Linuxを䜿甚しおいる堎合、アドバむスは必芁ありたせん。すべおを機胜させる方法は私よりもよく知っおいたす。むンストヌルは簡単です。 ダりンロヌドしおむンストヌルしおください。 むンストヌル埌、ghciコマンドを実行したす。 芋぀からない堎合は、PATHにフォルダヌ "... \ Haskell Platform \ xyz0 \ bin \"を远加したす。 Haskellコヌドは「* .hs」ファむルに保存されたす。 HugIDEたたはメモ垳++私ず同じようにで䜜成できたす。 Haskellプラットフォヌムをむンストヌルするず、* .hsファむルがGHCiむンタヌプリタヌに関連付けられたす。これは、埌で芋るように非垞に䟿利です。 Hackageのすべおの長所の巚倧なリポゞトリをダりンロヌドするこずもできたす。そこには、簡単なゲヌムadvgameがありたす。 圌女は、自分自身を曞く䞊で私にずっおタむプず基準点でした。

ク゚スト甚のフォルダヌを䜜成したす。 空のQuestMain.hsファむルを䜜成しお実行したす。 GHCiむンタヌプリタヌのコン゜ヌルが衚瀺されたす。これはデバッグに圹立ちたす。 GHCiがいく぀かのラむブラリをロヌドし、1ファむルのうち1フ​​ァむルを正垞にコンパむルし、「OK、ロヌドされたモゞュヌルMain」ず衚瀺されたす。コマンドプロンプトで「* Main>」ず入力したす。 いいえ、いいえ、プログラムを䜜成したせん。 次に、このツヌルを少し調べお、埌でプログラムのデバッグが簡単になるようにしたす。

*メむン> 4
4
*メむン> 2 + 4-7
-1
*メむン> 9 /  2 * 5.0 
0.9
*メむン>  - 1  + 4
3
*メむン> 7 == 7
本圓
*メむン> -5 > 0
停


数孊関数も䜿甚できたすsin x、cos x、tan x、atan x、abs x。

*メむン> sin 10 * sin 10 + cos 10 * cos 10
1.0
*メむン> sin  2 * cos 10  + tan 5
-4.374758876543559


Haskellは倧文字ず小文字を区別する蚀語ですC ++、Javaなど。 あなたは垞にcOS機胜を望んでいたこずを知っおいたすが、そうではありたせん。 「cos」のみがありたす。

*メむン> cos  cos  cos 0.5  
0.8026751006823349
*メむン> cos pi
-1.0


これはすべお予想され、理解できるこずです。 piは、数piを返す関数であり、匕数はありたせん。 䞉角関数は1぀の匕数を受け取りたす。 耇数の匕数を持぀関数はどうですか 構文は単玔です最初に関数の名前、次に匕数。 角かっこ、コンマ、たたはセミコロンなし。

*メむン> logBase 2 2
1.0
*メむン> logBase  sin 2  2
-7.28991425837762


2番目の䟋では、sin 2をかっこで囲み、これがlogBase関数の1匕数になるようにするこずが重芁です。 これが行われない堎合、むンタプリタは2぀の代わりに3぀の匕数sin、2、2をlogBase関数に枡したず芋なし、誓いたす

*メむン> logBase sin 2 2

<むンタラクティブ>  1  1 
 Floating  a0- > a0  の むンスタンスはありたせん
' logBase 'の䜿甚に起因する
考えられる修正  Floating  a0- > a0  の むンスタンス宣蚀を远加したす
匏内 logBase sin 2 2
「it」の方皋匏it = logBase sin 2 2
..................


圌が私たちに蚀ったこずは、私たちはただそれに぀いお考えたせん。 これは王宀の問題ではなく、もっず重芁な問題がありたす。

数孊的な機胜を含むその他の機胜は、Haskellプラットフォヌムにある付属ドキュメント「GHCラむブラリドキュメント」にありたす。 デフォルトでは、Preludeモゞュヌルにあるすべおの機胜が䜿甚可胜です。 このモゞュヌルをロヌドしなかった、それ自䜓をロヌドしたした。 眪、コス、その他が定矩されおいたす。 Preludeには䟿利な機胜が倚数含たれおいたす。これらは最も頻繁に䜿甚されるため、たずめられおいたす。 Preludeのドキュメントをチェックするず、次のような異垞な、奇劙な構成が衚瀺されたす。

単語 :: 文字列 -> [ 文字列 ]


たたはこれも

Eq a => Eq  たぶん a 


分かりたせんか 䜕も、私たちはそれを理解したせん。


䜕かがありたすが、少しだけ行を䜜っおみたしょう。 Haskellの文字列は、二重匕甚笊内のC文字ず同じように芋えたす。 特殊文字\ n「改行」も機胜したす。

*メむン> 「こんにちは、䞖界」
「Hello world」
*メむン> 「こんにちは、 \ nワヌルド」
「こんにちは、 \ n䞖界」


うたくいかなかったのは?? A. ghciで行を曞くずき、単玔にそれを繰り返したす。 同様に、単䞀の数字たたはTrueを繰り返したす。

*メむン> 1,000,000
1,000,000
*メむン> True
本圓


これはghciデバッグ出力です。これを呌び出したしょう。 行も番号も実際のコン゜ヌルにただ送信されおいたせん。 実際のコン゜ヌルで印刷する行を送信したしょう

* Main > putStrLn "こんにちは、 \ nワヌルド"
こんにちは
䞖界


さお、putStrLn関数は文字列を受け入れ、実際のコン゜ヌルに出力したした。 ghciは結果を再珟したした。 曞き蟌みputStrLn、文字列を受け入れ、画面に衚瀺したす。 「++」操䜜で接続するこずにより、2行を出力できたす。

* Main > putStrLn  "Hello、world" ++ " \ nここに行きたす" 
ハロヌワヌルド
行くぞ


ghciが正しくなるようにブラケットが必芁です。 括匧がなければ、圌は文字通り次のこずを考えるでしょう
putStrLn "こんにちは、䞖界" ++ "\ nここに行きたす" <=>putStrLn "Hello、world"++ "\ nHere we go"
コン゜ヌルにstring1 add string2を远加しようずしおいるため、これは埅ち䌏せです。 出力に文字列を远加するにはどうすればよいですか 䞍正行為の内容は次のずおりです。

* Main > putStrLn "Hello、world" ++ " \ nここに行きたす"

<むンタラクティブ>  1  1 
期埅されるタむプ [ a0 ]を実際のタむプ ' IO   'ず䞀臎させるこずができたせんでした
' putStrLn 'の呌び出しの戻り 型
最初の匕数 '  ++  ' では、぀たり
' putStrLn “ Hello、world” '
匏内 putStrLn "Hello、world" ++ " \ nここに行きたす"


コン゜ヌルぞの2぀の出力も加算されたせん。 さらにいく぀かの誀ったオプション

* Main > putStrLn "Hello、world" ++ putStrLn " \ n どうぞ "
* Main > putStrLn "Hello、world" PutStrLn " \ nここに行きたす"
* Main > "Hello、world" ++ putStrLn " \ n どうぞ 


putStrLn関数がたったくない堎合のオプションは機胜したすが、「実際」ではなく、文字列のデバッグ出力を取埗したす。 「\ nHere we go」ずいう郚分が必芁でした。 次のようにではなく、新しい行から印刷されたした。

* Main > "Hello、world" ++ " \ nここに行きたす"
「こんにちは \ nここに行きたす」


誀ったオプションのそれぞれを完了しようずするこずで、ghciがあなたをどう思うかを知るこずができたす。 私たちは皆、これらのむンタヌプリタヌずコンパむラヌのペティネスを知っおいたす..それらが私たちの䞖界に䜏んでいないかのように、正確で正確なものだけを䞎えおください。

たあ、実際にそうです。 Haskellには独自の䞖界ず独自の法埋がありたす。 法埋では、匏のタむプが正しいこずが必芁です。 Haskellは非垞に匷く型付けされた蚀語です。 関数、パラメヌタヌ、匏-すべおに特定のタむプがありたす。 異なるタむプのパラメヌタヌが必芁な堎合、パラメヌタヌを関数に枡すこずはできたせん。 実際のコン゜ヌルで数字を入力しおみおください。

*メむン> putStrLn 5

<むンタラクティブ>  1  10 
 Num String の むンスタンスはありたせん
リテラル「 5 」から生じる
考えられる修正  Num String の むンスタンス宣蚀を远加したす
' putStrLn 'の最初の匕数、぀たり ' 5 '
匏内 putStrLn 5
「it」の方皋匏it = putStrLn 5


通蚳者が䜕かに぀いおおなじみの宣誓をしおいるのがわかりたす。 putStrLn関数は、文字列String型のみを必芁ずしたすが、数倀を受け取りたす。 タむプが䞀臎したせん。=>競合がありたす。 これを行うこずができたす

* Main > putStrLn  show 5 
5


show関数は、可胜であれば、匕数を文字列に倉換し、putStrLnを䜿甚しお出力したす。 関数show 5を実行するず、文字列「5」が取埗されるように、次のように入力したす。

* Main > putStrLn  "String and" ++  show 5  ++ " \ n-再び文字列。" 
ストリング ず 5
-再び文字列。


show関数は、倚くのタむプを文字列に倉換できたす。 圌女はク゚ストで非垞に圹立ちたす。

* Main > putStrLn  "sin ^ 2 5 + cos ^ 2 5 =" ++ show  sin 5 * sin 5 + cos 5 * cos 5  
sin ^ 2 5 + cos ^ 2 5 = 0.9999999999999999


もちろん、putStrLnも同様に䟿利です。 理論的には、PascalプロシヌゞャwriteLnも䜕も返さないため、䜕も返すべきではありたせん。 しかし、Haskellでは、関数は垞に䜕かを返したす。 これを確認しおください ghciでいく぀かのナヌティリティコマンドを入力できたす。「t」「type」コマンドは、匏のタむプを衚瀺したす。

*メむン> t 3 == 3
3 == 3 :: ブヌル
*メむン> t 3 / = 3
3 / = 3 :: ブヌル
* Main > 「f」ず入力したす
'f' :: Char
* Main >  「I am a string」ず入力したす
「私は文字列です」 :: [ Char ]


ここで、匏は特別な皮類の関数ず芋なすこずができ、おそらくパラメヌタヌを受け取らず、必然的に結果を返したす。 putStrLn関数タむプは次のようになりたす。

*メむン> t putStrLn
putStrLn :: 文字列 -> IO  


この圢匏の蚘述数孊、他の関数型蚀語に出䌚っおいない堎合は、おそらく私にずっおはか぀おなかったように、少し珍しいでしょう。 しかし、すぐに良いものに慣れ、Haskellの型も同じように優れおいたす。 ほずんどの堎合、それらを指定する必芁はありたせん。Haskellはそれらを自分で削陀し、どこかで䞀臎しないものがあれば指で脅しさえしたす。 私たちはただ基本的なタむプからすべおの皮類のデザむンを芋おいたす、そしお、あなたはそれがどれほど䟿利であるかを感じるでしょう。 すべおの倉数が必芁な䞀郚のC ++ずは異なり、各芁玠が蚘述され、ペむントされ、登録されおいたす...

この堎合、putStrLnはStringを取り、IOを返したす。 コロンは、関数の名前ずそのタむプを区切りたす。 「putStrLnにはStringからIOたでの型がありたす」ず読むのが正しいでしょう。 文字列は、入力文字列のタむプです。 「IO」ず入力したす-入出力の䞍可欠な郚分入力/出力、あなたが掚枬した。 タむプ「IO」は、putStrLn関数がプログラムの「クリヌンでない」領域にふけるこずを瀺したす。 この゚リアでは、灜害でも䜕でも起こり埗たす。私たちはそれに぀いお慎重に考えなければなりたせん。 しかし、今のずころ、私たちは䜕も考える必芁がなく、IOに迷惑をかけさせたせん。 倧惚事が発生しない関数、副䜜甚が発生しない関数を蚘述しようずしたす。

これらは、玔粋な決定論ず呌ばれたす。このような関数は、同じ匕数に察しお同じ倀を返す必芁がありたす。 Haskell蚀語は、たさにこの抂念のために玔粋な関数型蚀語です。 もちろん、ここでは、異なる呌び出しで異なる結果を埗るこずができる関数たずえば、疑䌌乱数ゞェネレヌタヌをどう凊理するかずいう疑問が生じたす。 そしお、デヌタを倉曎する方法は メモリを操䜜する方法は キヌボヌド入力の読み方 結局のずころ、これはすべお非決定論に぀ながりたす。 Haskellには、これらの問題やその他の問題を適切に解決するための特別なメカニズム「モナド」がありたす。 今埌、この䌚話に戻りたす。


そのため、テキスト゚ディタヌQuestMain.hsで開きたす。 空がありたすが、これはほんの始たり、しきい倀です。 すぐに人魚がここで泳ぎ、ドラゎンが飛びたす。 それたでの間、2぀の数倀の積を蚈算する単玔な関数を䜜成したす。

prod x y = x * y


割り圓おを忘れおください Haskellには課題はありたせん 䞊にあるのは関数宣蚀です。 「等しい」ずは、prodが2぀の匕数xずyで機胜するこずを意味し、匏x * yず䞀臎したす。 この匏は、関数を呌び出すず評䟡されたす。 やっおみたしょう。 QuestMain.hsファむルを保存したす。 すでにghciコン゜ヌルを閉じおいる堎合は、再床実行したすghci QuestMain.hs。 コン゜ヌルが開いおいる堎合は、次のコマンドを入力したす。r-これにより、ghciが珟圚のファむル、぀たりQuestMain.hsを匷制的に再起動しおコンパむルしたす。

*メむン> r
[ 1 of 1 ] Mainのコンパむル H\ Haskell \ QuestTutorial \ Quest \ QuestMain。Hs 、解釈枈み
OK 、ロヌドされたモゞュヌルMain
*メむン>補品 3 5
15


うたくいく 動䜜しない堎合は、倧文字ず小文字の区別、QuestMain.hsが保存されおいるかどうか、このバヌゞョンがghciにロヌドされおいるかどうかを確認したす。数字3ず5はそれぞれ倉数xずyに関連付けられおいたす。 むンタヌプリタヌはprod 3 5を匏3 * 5で眮き換えたす。これは蚈算されたす。

*メむン>補品 3  2 + 3 
15
*メむン>補品 3  cos pi 
-3.0


さらにいく぀かの関数を䜜成しおテストしたす。 以䞋、ファむルに関数を蚘述するこずは指定しなくなりたしたが、ghciでテストしたす。たずえば、次のようになりたす。

printString str = putStrLn str
printSqrt x = putStrLn  " Sqrt of" ++ show x ++ "=" ++ show  sqrt x  

*メむン> printString "dfdf"
dfdf
*メむン> printSqrt 4
Sqrt 4.0 = 2.0
*メむン> printSqrt  -4 
平方根-4.0 = NaN


埌者の堎合、負の数の平方根は「Not a Number」ずいう結果になりたす。 この結論が私たちに合わず、文字列「x <0」を負のxに出力したいずしたす。 printSqrt関数をいく぀かの方法で曞き盎し、同時にいく぀かの非垞に有甚な構成芁玠を調べたす。

printSqrt1 x =
x < 0の 堎合
次に putStrLn "x <0"
else putStrLn  " Sqrt of" ++ show x ++ "=" ++ show  sqrt x  

printSqrt2 x = case x < 0 of
True- > putStrLn "x <0"
False- > putStrLn  " Sqrt of" ++ show x ++ "=" ++ show  sqrt x  

*メむン> printSqrt1  -4 
x < 0 
*メむン> printSqrt2  -4 
x < 0 


等号の埌にあるものはすべお、すべおのオプション代替を考慮に入れるべき匏であるため、他になければifはできたせん。 いく぀かのオプションを考慮しなかったが倱敗した堎合は、遞択肢が䞍完党であるずいう゚ラヌが衚瀺されたす。

printSqrt2 x = case x < 0 of
True- > putStrLn "x <0"

*メむン> r
...
*メむン> printSqrt2  -4 
x < 0 
*メむン> printSqrt2 10
***䟋倖H\ Haskell \ QuestTutorial \ Quest \ QuestMain 。 hs  12、16  -  13、41   ケヌスの非網矅的なパタヌン


たた、ケヌス構文では、むンデント「むンデント」が重芁であるこずに泚意しおください。 それらは同じでなければなりたせん-これはそこのスペヌスたたはタブにも適甚されたす。 コンパむルしおみおください

printSqrt2 x = case x < 0 of
True- > putStrLn "x <0"
False- > putStrLn  " Sqrt of" ++ show x ++ "=" ++ show  sqrt x  

*メむン> r
[ 1 of 1 ] Mainのコンパむル H\ Haskell \ QuestTutorial \ Quest \ QuestMain。Hs 、解釈枈み

H\ Haskell \ QuestTutorial \ Quest \ QuestMain hs 14  23 
入力での゚ラヌが発生したした ' -> '
倱敗し、モゞュヌルがロヌドされたしたなし。


ケヌスのデザむンはずおも䟿利です。 if-then-elseよりも読みやすく、拡匵しやすいです。 もちろん、ネストされた䞀連のif-then-elseで衚珟できるため、構造は同等です。 秘密を教えおください。ケヌスはさらに機胜的であり、すぐにわかりたす。 それたでの間、远加の䟋。 少し人工的ですが、それは問題ではありたせん

thinkAboutSquaredX x = ケヌス x
0.0 -> 「0 * 0 = 0であるため、xは0だず思いたす。」
1.0- > "1 * 1 = 1であるため、xは1です。"
4.0 -> 「2 x 2 = 4なので、xは2です。」
9.0- > "x = 3."
16.0- > 「たさか、x = 4」
25.0 -> 「HaX = 5」
それ以倖の堎合 -> x < 0の 堎合、 「x <0」 else "Sqrt" ++ show x ++ "=" ++ show  sqrt x 



*メむン> thinkAboutSquaredX 1
「1 * 1 = 1であるため、Xは1です。」
*メむン> thinkAboutSquaredX 25
「ハ x = 5」

それ以倖の堎合の単語は、 「そうでなければ」も意味したす。 残りのオプションが順番に近づいおいない堎合 、 そうでない堎合に適しおいたす。これはTrueの同矩語にすぎないためです。 䞋郚にあるオプションはすべお䜿甚できなくなるため、䞭倮に挿入しないでください。

thinkAboutSquaredX x = ケヌス x
0.0 -> 「0 * 0 = 0であるため、xは0だず思いたす。」
1.0- > "1 * 1 = 1であるため、xは1です。"
そうでなければ -> if x < 0 then “ x <0” else “ Sqrt” ++ show x ++ "=" ++ show  sqrt x 
4.0 -> 「2 x 2 = 4なので、xは2です。」
9.0- > "x = 3."
16.0- > 「たさか、x = 4」
25.0- > 「ハ x = 5」


コヌドはコンパむルされたすが、䞀臎するサンプルの共通郚分に関する譊告が衚瀺されたす。

*メむン> r
[ 1 of 1 ] Mainのコンパむル H\ Haskell \ QuestTutorial \ Quest \ QuestMain。Hs 、解釈枈み

H\ Haskell \ QuestTutorial \ Quest \ QuestMain hs 16  24 
譊告パタヌンマッチ es が重耇しおいたす
代替ケヌスの堎合 
4.0- > ...
9.0- > ...
16.0- > ...
25.0- > ...
OK 、ロヌドされたモゞュヌルMain
*メむン> thinkAboutSquaredX 1
「1 * 1 = 1であるため、Xは1です。」
*メむン> thinkAboutSquaredX 9
「Sqrt 9.0 = 3.0」
* Main >  それ以倖の堎合は t
そうでなければ :: Bool
*メむン> それ以倖の堎合 == True
本圓


ここでやっおいるこずを思い出しおくださいク゚ストを曞いおいたす すべおのク゚ストには、堎所移動パスによる、オブゞェクト、プレむダヌアクションの3぀のこずがありたす。 番号がある堎合、どのようにしお堎所の説明を取埗できたすか 解決策は次のずおりです。

describeLocation locNumber = ケヌス locNumber
1- > 「朚補のテヌブルの真ん䞭の郚屋に立っおいたす。」
2- > 「あなたは小さな朚補のフェンスの埌ろのナむトガヌデンの前に立っおいたす。」
-ここに他の堎所の説明を挿入したす。
それ以倖の堎合 -> "䞍明な堎所。"

* Main > describeLocation 2
「あなたは小さな朚補のフェンスの埌ろのナむトガヌデンの前に立っおいたす。」
* Main > describeLocation 444
「堎所が䞍明です。」


泚意しおくださいコメント 単䞀行コメントは、二重のマむナス蚘号で始たりたすSQLのように。 耇数行の文字の堎合、{-および-}が䜿甚されたす。

describeLocation locNumber = ケヌス locNumber
1- > 「朚補のテヌブルの真ん䞭の郚屋に立っおいたす。」
2- > 「あなたは小さな朚補のフェンスの埌ろのナむトガヌデンの前に立っおいたす。」
{-ここに他の堎所の説明を挿入したす。
たたはここ。
adfsdf少数のfef jel jle jkjlefjaiejeo-}
それ以倖の堎合 -> "䞍明な堎所。"


よくここに。 基本的なHaskellコンストラクトのすべおを知るこずはできたせんでした。 putStrLn、show、case-construction、lines、ghci-これらはすべお将来的に必芁になりたす。 ク゚スト甚の関数も1぀䜜成したした。 おそらく十分です。 第二郚では、ク゚ストの䜜業を開始し、その過皋で他のすばらしいHaskellトリックを孊びたす。 冒険が埅っおいたす

統合するには、次のタスクを解決できたす。

1.関数zを定矩し、いく぀かの倀に぀いお蚈算したす。
t =7 * x ^ 3-lnabsa/2.7 * b
y = sint-sina
z = 8.87 * y ^ 3 + arctant
ここで、x、a、bはFloat型の倉数です。

2.関数yを定矩し、いく぀かの倀に぀いお蚈算したす。
| lnabssinxx> 5の堎合
y = | x <= 5か぀a <= 3の堎合、x ^ 2 + a ^ 2
| x / a + 7.8 * a x <= 5およびa> 3の堎合
ここで、x、aはFloat型の倉数です。


目次、リファレンスのリスト、および远加情報は、グリヌティングにありたす。

Source: https://habr.com/ru/post/J120759/


All Articles