Repository: nushio3/learn-haskell Branch: master Commit: eda0fd0b33e9 Files: 98 Total size: 56.1 KB Directory structure: gitextract_1t8rr68b/ ├── README.md ├── Tsukuba-2016.odp ├── choose-name/ │ ├── LICENSE │ ├── Setup.hs │ ├── choose-name.cabal │ ├── src/ │ │ └── Main.hs │ └── stack.yaml ├── concepts.md ├── desugar-monad.hs ├── exercise-1-hello-cat/ │ └── TASK.md ├── exercise-10-free/ │ └── TASK.md ├── exercise-3-string-Num/ │ ├── LICENSE │ ├── Setup.hs │ ├── String-Num.cabal │ ├── TASK.md │ ├── src/ │ │ └── Main.hs │ └── stack.yaml ├── exercise-4-brain-twister/ │ ├── TASK.md │ ├── input-1.txt │ ├── input-2.txt │ ├── input-3.txt │ ├── output-1.txt │ ├── output-2.txt │ └── output-3.txt ├── exercise-5-1-fast-reverse/ │ ├── TASK.md │ └── with-string.hs ├── exercise-5-2-confuse-prelude/ │ ├── LICENSE │ ├── Setup.hs │ ├── TASK.md │ ├── app/ │ │ └── Main.hs │ ├── confuse-prelude.cabal │ ├── src/ │ │ └── Lib.hs │ └── stack.yaml ├── exercise-6-1-data-Vec/ │ ├── LICENSE │ ├── Setup.hs │ ├── TASK.md │ ├── app/ │ │ └── Main.hs │ ├── src/ │ │ └── Data/ │ │ └── Vec.hs │ ├── stack.yaml │ ├── test/ │ │ └── Spec.hs │ └── vec.cabal ├── exercise-7-nabe/ │ ├── LICENSE │ ├── Setup.hs │ ├── TASK.md │ ├── nabe.cabal │ ├── recipe.txt │ ├── src/ │ │ └── Main.hs │ └── stack.yaml ├── exercise-8-1-safe-pred/ │ ├── LICENSE │ ├── Setup.hs │ ├── TASK.md │ ├── safe-pred.cabal │ ├── src/ │ │ └── Main.hs │ └── stack.yaml ├── exercise-8-2-learn-parser/ │ ├── LICENSE │ ├── Setup.hs │ ├── TASK.md │ ├── input-arith-1.txt │ ├── input-arith-2.txt │ ├── input-arith-3.txt │ ├── input-arith-4.txt │ ├── input-arith-5.txt │ ├── learn-parser.cabal │ ├── output-arith-1.txt │ ├── output-arith-2.txt │ ├── output-arith-3.txt │ ├── output-arith-4.txt │ ├── output-arith-5.txt │ ├── src/ │ │ ├── parse-S-expression.hs │ │ ├── parse-arithmetic.hs │ │ ├── parse-integer.hs │ │ └── parse-question.hs │ └── stack.yaml ├── exercise-9-traversable-Vec/ │ ├── LICENSE │ ├── Setup.hs │ ├── TASK.md │ ├── app/ │ │ ├── Main.hs │ │ └── geometry.hs │ ├── src/ │ │ └── Data/ │ │ └── Vec.hs │ ├── stack.yaml │ ├── test/ │ │ └── Spec.hs │ └── vec.cabal ├── greet-using-overloaded-string.hs ├── greet-using-string.hs ├── greet-using-text.hs ├── greet-winter.txt ├── hello-world.hs ├── how-to-submit.txt ├── kazu.hs ├── monad-compose.hs ├── monad-family-tree.hs ├── parser-sample.hs ├── quicktest.hs ├── setup-tsukuba-2016.sh ├── tips.md ├── typeclass.hs ├── unsafe-io.hs └── world-state.hs ================================================ FILE CONTENTS ================================================ ================================================ FILE: README.md ================================================ # すごいHaskell つくばで学ぼう! 2016年 筑波大学 Haskell集中講義の資料です。 - 最新の講義資料はこちらを参照してください: https://github.com/nushio3/learn-haskell/blob/master/Tsukuba-2016.pdf - 授業中随時、質問が出たポイントをまとめていきます: https://github.com/nushio3/learn-haskell/blob/master/tips.md ================================================ FILE: choose-name/LICENSE ================================================ Copyright Takayuki Muranushi (c) 2015 All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Takayuki Muranushi nor the names of other contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================ FILE: choose-name/Setup.hs ================================================ import Distribution.Simple main = defaultMain ================================================ FILE: choose-name/choose-name.cabal ================================================ name: choose-name version: 0.1.0.0 synopsis: Simple project template from stack description: Please see README.md homepage: http://github.com/nushio3/choose-name#readme license: BSD3 license-file: LICENSE author: Takayuki Muranushi maintainer: muranushi@gmail.com copyright: 2010 Author Here category: Web build-type: Simple cabal-version: >=1.10 executable choose-name hs-source-dirs: src main-is: Main.hs default-language: Haskell2010 build-depends: base >= 4.7 && < 5 , process , random , unix ================================================ FILE: choose-name/src/Main.hs ================================================ module Main where import Control.Monad import Data.List import System.Environment (getArgs) import System.IO import System.Posix.Unistd import System.Process (system) import System.Random draw :: [String] -> IO () draw names0 = do let names = names0 ++ names0 let getSortedNames = do rs <- replicateM (length names) randomIO return $ map snd $ sort $ zip (rs::[Int]) names sn0 <- getSortedNames forM sn0 $ \n0 -> do system "clear" spinNames <- take 50 <$> concat <$> replicateM 10 getSortedNames forM spinNames $ \n1 -> do putStr $ n1 ++ "\r" hFlush stdout usleep 10000 system "clear" putStrLn $ n0 ++ " 様" getLine return () main :: IO () main = do argv <- getArgs contents <- mapM readFile argv let names = lines $ concat contents forever $ draw names ================================================ FILE: choose-name/stack.yaml ================================================ # For more information, see: https://github.com/commercialhaskell/stack/blob/release/doc/yaml_configuration.md # Specifies the GHC version and set of packages available (e.g., lts-3.5, nightly-2015-09-21, ghc-7.10.2) resolver: lts-5.0 # Local packages, usually specified by relative directory name packages: - '.' # Packages to be pulled from upstream that are not in the resolver (e.g., acme-missiles-0.3) extra-deps: [] # Override default flag values for local packages and extra-deps flags: {} # Extra package databases containing global packages extra-package-dbs: [] # Control whether we use the GHC we find on the path # system-ghc: true # Require a specific version of stack, using version ranges # require-stack-version: -any # Default # require-stack-version: >= 0.1.4.0 # Override the architecture used by stack, especially useful on Windows # arch: i386 # arch: x86_64 # Extra directories used by stack for building # extra-include-dirs: [/path/to/dir] # extra-lib-dirs: [/path/to/dir] ================================================ FILE: concepts.md ================================================ 変数 リテラル 関数適用 Let式 λ式 Case式 型 型注釈 型クラス リスト リスト内包表記 タプル 無限リスト quicksort 素数リスト 文字規則 パターンマッチ ガード 演算子の優先順位と定義 関数の部分適用 演算子と関数の相互変換 再帰と高階関数の使い方 モジュール データ型の自作 型クラスの自作 IO Functor Applicative Monad Maybeモナド Listモナド Stateモナド トランスフォーマー https://wiki.haskell.org/Typeclassopedia#Functor ================================================ FILE: desugar-monad.hs ================================================ main :: IO () main = getLine >>= (\x -> getLine >>= (\y -> let z = x++y in putStrLn z)) ================================================ FILE: exercise-1-hello-cat/TASK.md ================================================ # exercise 1. Hello, cat! ## task 1 `hello-world` という名前のプロジェクトを作り、 実行すると"hello world"と表示するプログラムを作ってください。 ただし、次の2つの関数を使ってください。 `interact :: (String -> String) -> IO ()` `const :: a -> b -> a` ## task 2 `cat` という名前のプロジェクトで、 実行すると標準入力から入力された内容を1行づつ標準出力に出力するプログラムを作ってください。 ただし、次の2つの関数を使ってください。 `interact :: (String -> String) -> IO ()` `id :: a -> a` ================================================ FILE: exercise-10-free/TASK.md ================================================ # exercise 10. This is a free-style task! 自分の気になるHaskellのライブラリを調べて使って、独自のHaskellプログラムを作ってみてください。 ================================================ FILE: exercise-3-string-Num/LICENSE ================================================ Copyright Takayuki Muranushi (c) 2015 All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Takayuki Muranushi nor the names of other contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================ FILE: exercise-3-string-Num/Setup.hs ================================================ import Distribution.Simple main = defaultMain ================================================ FILE: exercise-3-string-Num/String-Num.cabal ================================================ name: String-Num version: 0.1.0.0 synopsis: Simple project template from stack description: Please see README.md homepage: http://github.com/nushio3/String-Num#readme license: BSD3 license-file: LICENSE author: Takayuki Muranushi maintainer: muranushi@gmail.com copyright: 2010 Author Here category: Web build-type: Simple cabal-version: >=1.10 executable String-Num hs-source-dirs: src main-is: Main.hs default-language: Haskell2010 build-depends: base >= 4.7 && < 5 ================================================ FILE: exercise-3-string-Num/TASK.md ================================================ # exercise 3. instance Num String Haskellではリストの結合は演算子 ++ で行います。 他のプログラミング言語では、 + 演算子で文字列を結合したり、`整数n * 文字列`という構文で文字列をn回繰り返した文字列を生成できるものもあります。時にはこちらが便利に感じることもありますね! このフォルダにあるプロジェクトは、String同士を + で演算しているため、このままではコンパイルできません。 String 同士の + 演算を定義して、このプログラムが動くようにしてください。 ## 発展課題 `整数n * 文字列` という構文も使えるようにできないでしょうか? ================================================ FILE: exercise-3-string-Num/src/Main.hs ================================================ module Main where -- {- Hint -} -- instance Num String where a + b = a ++ b -- ... main :: IO () main = do putStrLn "May I have your name?" name <- getLine putStrLn $ "Congratulations, " + name + " has now mastered class Num!" -- {- Can you also make these work? -} -- putStrLn 5963 -- putStrLn $ 3 * ("All hail " + name + "! ") ================================================ FILE: exercise-3-string-Num/stack.yaml ================================================ # For more information, see: https://github.com/commercialhaskell/stack/blob/release/doc/yaml_configuration.md # Specifies the GHC version and set of packages available (e.g., lts-3.5, nightly-2015-09-21, ghc-7.10.2) resolver: lts-5.0 # Local packages, usually specified by relative directory name packages: - '.' # Packages to be pulled from upstream that are not in the resolver (e.g., acme-missiles-0.3) extra-deps: [] # Override default flag values for local packages and extra-deps flags: {} # Extra package databases containing global packages extra-package-dbs: [] # Control whether we use the GHC we find on the path # system-ghc: true # Require a specific version of stack, using version ranges # require-stack-version: -any # Default # require-stack-version: >= 0.1.4.0 # Override the architecture used by stack, especially useful on Windows # arch: i386 # arch: x86_64 # Extra directories used by stack for building # extra-include-dirs: [/path/to/dir] # extra-lib-dirs: [/path/to/dir] ================================================ FILE: exercise-4-brain-twister/TASK.md ================================================ # exercise 4. reverse the string ある学説によれば、ヒトは英語を読むとき、英単語の「最初の文字」「最後の文字」「途中の文字の集合」を認識するようになっているため、英文を書くとき、英単語の最初と最後以外の文字の順序を入れ替えておいても、ほとんどの人は間違いに気づかずに読めてしまうそうです。 本当でしょうか? これを検証するために、スペース区切りの文字列を入力に受け取って、各単語の最初と最後の文字以外を逆順にしてしまうプログラムを作ってください。 このフォルダにある input-n.txt を標準入力から読ませると、対応する output-n.txt を出力するようなプログラムになればokです。 ================================================ FILE: exercise-4-brain-twister/input-1.txt ================================================ a ab abc abcd abcde abcdef abc123 !"#$%& ================================================ FILE: exercise-4-brain-twister/input-2.txt ================================================ The purpose of this project is to design a high-level language for implementing explicit partial-differential equations solvers on supercomputers as well as today’s advanced personal computers. A language to describe the knowledge on algebraic concepts, physical equations, integration algorithms, optimization techniques, and hardware designs --- all the necessaries of the simulations in abstract, modular, re-usable and combinable forms. ================================================ FILE: exercise-4-brain-twister/input-3.txt ================================================ Why dsdit tohu psimore scuh a buoetuaes dya, And mkae me tevarl ftroh wuohtit my ckaol, To let bsae cduols okatre'e me in my wya, Hnidig thy brevary in tiehr retton sekom? 'iTs not eguonh taht tguorhh the cuold tohu bkaer, To dry the rian on my setaeb-mrotn feca, For no man wlel of scuh a svlae can saepk Taht hlaes the wnuod and cerus not the decargsi: Nor can thy smahe gvie pisyhc to my gfeir; Tguohh tohu rtnepe, yet I hvae slitl the lsso: The o'redneffs sorrow ldnes but waek reilef To him taht braes the snortg o'ecneffs cssor. Ah! but tsohe traes are prael wcihh thy lvoe ssdeh, And tehy are rcih and rosnam all ill dsdee. ================================================ FILE: exercise-4-brain-twister/output-1.txt ================================================ a ab abc acbd adcbe aedcbf a21cb3 !%$#"& ================================================ FILE: exercise-4-brain-twister/output-2.txt ================================================ The psoprue of tihs pcejort is to dgisen a hevel-hgil lgaugnae for initnemelpmg eicilpxt paitnereffid-laitral enoitauqs srevlos on sretupmocrepus as wlel as t’yados aecnavdd panosrel csretupmo. A lgaugnae to dbircsee the kgdelwone on aiarbeglc cstpecno, pacisyhl esnoitauq, ioitargetnn asmhtirogl, ooitazimitpn tseuqinhce, and hrawdrae dngises --- all the neirasseces of the snoitalumis in atcartsb, mraludo, rlbasu-ee and clbanibmoe fsmro. ================================================ FILE: exercise-4-brain-twister/output-3.txt ================================================ Why didst thou promise such a beauteous day, And make me travel forth without my cloak, To let base clouds o'ertake me in my way, Hiding thy bravery in their rotten smoke? 'Tis not enough that through the cloud thou break, To dry the rain on my storm-beaten face, For no man well of such a salve can speak That heals the wound and cures not the disgrace: Nor can thy shame give physic to my grief; Though thou repent, yet I have still the loss: The offender's sorrow lends but weak relief To him that bears the strong offence's cross. Ah! but those tears are pearl which thy love sheds, And they are rich and ransom all ill deeds. ================================================ FILE: exercise-5-1-fast-reverse/TASK.md ================================================ # exercise 5-1. faster reverse exercise 4. reverse the string で作ったプログラムは、文字列をCharのリストとして扱っているため、実行速度が遅くなっています。文字列処理用のライブラリtext https://hackage.haskell.org/package/text を利用して、このプログラムをより高速にしてみましょう。 String を利用する版と、Textを利用する版のプログラムを作り、両方のプログラムの実行結果が一致することを確認してください。 また、両方のプログラムについて、ファイルを処理する時間をファイルサイズ等の関数として測定してみてください。 (計測結果、またはそのファイルの所在を、SOLUTION ファイルに記入すること。) 大きな英文テキストファイルは例えば、以下のURLからダウンロードできます。 * http://www.geocities.jp/f9305710/PAI1000000.html (1.2MB) * http://norvig.com/big.txt (6.2MB) ================================================ FILE: exercise-5-1-fast-reverse/with-string.hs ================================================ import System.IO wordreverse :: [Char] -> [Char] wordreverse xs | length xs < 2 = xs | otherwise = do take 1 xs ++ (reverse $ drop 1 (take ((length xs) - 1) xs )) ++ drop (length xs -1) xs main :: IO () main = do strings <- getLine putStrLn $unwords $map wordreverse $words strings f<- isEOF if f then return() else main ================================================ FILE: exercise-5-2-confuse-prelude/LICENSE ================================================ Copyright Takayuki Muranushi (c) 2015 All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Takayuki Muranushi nor the names of other contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================ FILE: exercise-5-2-confuse-prelude/Setup.hs ================================================ import Distribution.Simple main = defaultMain ================================================ FILE: exercise-5-2-confuse-prelude/TASK.md ================================================ # exercise 5-2. Confuse the Prelude! このプロジェクトの実行ファイルは`app/Main.hs`です。 このプログラムを普通に実行すると、 5 + 100 * 7 + 10 を計算して715 と表示されます。 演算子 + と * の意味と優先順位を入れ替えて、このプログラムが 570 と表示するようにしてください。 つまり、 5 + 100 * 7 + 10 という式が、 + が乗算、 * が加算であるうえに、 優先順位が(5 + 100) * (7 + 10)なので、 (5 + 100) * (7 + 10) = (500) * (70) = 570 と解釈されるようにしてください。 なお、他のモジュールファイルはいくらでも作ってかまいませんが、app/Main.hsは import文以外の部分を編集してはいけません。 import文はいくら追加・削除しても大丈夫です。 1. Main.hsにおいて、Preludeが提供する + , * 識別子を隠し、自作のライブラリLibが提供する +, * を利用するようにします。 2. src/Lib.hs において、 演算子 + と * を、所定の意味と優先順位を持つように定義します。 3. 演算子の優先順位と結合性は、予約語 infix / infixl / infixr で指定します。 + や * の元々の優先順位については :info で調べられます! ================================================ FILE: exercise-5-2-confuse-prelude/app/Main.hs ================================================ module Main where {-  このプログラムを普通に実行すると、  715 と表示されます。  演算子 + と * の意味と優先順位を入れ替えて、このプログラムが 570 と表示するようにしてください。 なお、他のモジュールファイルはいくらでも作ってかまいませんが、このファイルは import文以外の部分を編集してはいけません。  import文はいくら追加・削除しても大丈夫です。 -} import Lib main :: IO () main = do print $ 5 + 100 * 7 + 10 ================================================ FILE: exercise-5-2-confuse-prelude/confuse-prelude.cabal ================================================ name: confuse-prelude version: 0.1.0.0 synopsis: Initial project template from stack description: Please see README.md homepage: http://github.com/nushio3/confuse-prelude#readme license: BSD3 license-file: LICENSE author: Takayuki Muranushi maintainer: muranushi@gmail.com copyright: 2010 Author Here category: Web build-type: Simple -- extra-source-files: cabal-version: >=1.10 library hs-source-dirs: src exposed-modules: Lib build-depends: base >= 4.7 && < 5 default-language: Haskell2010 executable i-am-confused hs-source-dirs: app main-is: Main.hs ghc-options: -threaded -rtsopts -with-rtsopts=-N build-depends: base , confuse-prelude default-language: Haskell2010 ================================================ FILE: exercise-5-2-confuse-prelude/src/Lib.hs ================================================ module Lib ( someFunc ) where someFunc :: IO () someFunc = putStrLn "someFunc" ================================================ FILE: exercise-5-2-confuse-prelude/stack.yaml ================================================ # For more information, see: https://github.com/commercialhaskell/stack/blob/release/doc/yaml_configuration.md # Specifies the GHC version and set of packages available (e.g., lts-3.5, nightly-2015-09-21, ghc-7.10.2) resolver: lts-5.0 # Local packages, usually specified by relative directory name packages: - '.' # Packages to be pulled from upstream that are not in the resolver (e.g., acme-missiles-0.3) extra-deps: [] # Override default flag values for local packages and extra-deps flags: {} # Extra package databases containing global packages extra-package-dbs: [] # Control whether we use the GHC we find on the path # system-ghc: true # Require a specific version of stack, using version ranges # require-stack-version: -any # Default # require-stack-version: >= 0.1.4.0 # Override the architecture used by stack, especially useful on Windows # arch: i386 # arch: x86_64 # Extra directories used by stack for building # extra-include-dirs: [/path/to/dir] # extra-lib-dirs: [/path/to/dir] ================================================ FILE: exercise-6-1-data-Vec/LICENSE ================================================ Copyright Takayuki Muranushi (c) 2015 All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Takayuki Muranushi nor the names of other contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================ FILE: exercise-6-1-data-Vec/Setup.hs ================================================ import Distribution.Simple main = defaultMain ================================================ FILE: exercise-6-1-data-Vec/TASK.md ================================================ # exercise 6-1. 3次元ベクトルを表す型を作ろう app/Main.hs では3次元ベクトルを表す型 Vec が使える前提でプログラムを書いています。 この型は Data/Vec.hs にて ``` data Vec a = Vec a a a ``` として定義されかかっていますが、実装はまだ途中です。 1. src/Data/Vec.hs を編集して、 app/Main.hs が動くようにしてください! 2. test/Spec.hs にはこのライブラリをテストするプログラムが入っています。 `stack test` を実行して、あたなが実装したモジュール Data.Vec がテストを通ることを確認してください。 ================================================ FILE: exercise-6-1-data-Vec/app/Main.hs ================================================ module Main where import Data.Vec main :: IO () main = do let u, v :: Vec Integer v = Vec 1 2 3 u = Vec 10 10 10 print $ u + v -- Vec 11 12 13 と表示されてほしい! print $ u ・ v -- 60 と表示されてほしい! print $ u × v -- Vec (-10) 20 (-10) と表示されてほしい! ================================================ FILE: exercise-6-1-data-Vec/src/Data/Vec.hs ================================================ module Data.Vec where data Vec a = Vec a a a (・) :: Vec a -> Vec a -> a (Vec ax ay az) ・ (Vec bx by bz) = undefined (×) :: Vec a -> Vec a -> Vec a (Vec ax ay az) × (Vec bx by bz) = undefined ================================================ FILE: exercise-6-1-data-Vec/stack.yaml ================================================ # For more information, see: https://github.com/commercialhaskell/stack/blob/release/doc/yaml_configuration.md # Specifies the GHC version and set of packages available (e.g., lts-3.5, nightly-2015-09-21, ghc-7.10.2) resolver: lts-5.0 # Local packages, usually specified by relative directory name packages: - '.' # Packages to be pulled from upstream that are not in the resolver (e.g., acme-missiles-0.3) extra-deps: [] # Override default flag values for local packages and extra-deps flags: {} # Extra package databases containing global packages extra-package-dbs: [] # Control whether we use the GHC we find on the path # system-ghc: true # Require a specific version of stack, using version ranges # require-stack-version: -any # Default # require-stack-version: >= 0.1.4.0 # Override the architecture used by stack, especially useful on Windows # arch: i386 # arch: x86_64 # Extra directories used by stack for building # extra-include-dirs: [/path/to/dir] # extra-lib-dirs: [/path/to/dir] ================================================ FILE: exercise-6-1-data-Vec/test/Spec.hs ================================================ import Control.Applicative import Test.Framework (defaultMain, testGroup) import Test.Framework.Providers.API (Test) import Test.Framework.Providers.QuickCheck2 (testProperty) import Test.QuickCheck.Arbitrary import Data.Vec instance Arbitrary a => Arbitrary (Vec a) where arbitrary = Vec <$> arbitrary <*> arbitrary <*> arbitrary tests :: [Test] tests = [ testProperty "addition of Vec is associative." $ \u v w -> u+(v+w) == (u+v)+ (w :: Vec Integer) , testProperty "addition of Vec is commutative." $ \u v -> u+v == v + (u :: Vec Integer), testProperty "zero." $ \v -> v +0 == (v :: Vec Integer), testProperty "one." $ \v -> 1*v == (v :: Vec Integer), testProperty "negate." $ \v -> v - v == (0 :: Vec Integer), testProperty "distributive vector." $ \a u v -> fromInteger a*(u+v) ==fromInteger a*u +fromInteger a * (v :: Vec Integer), testProperty "distributive scalar." $ \a b v -> fromInteger (a+b)*v == fromInteger a*v+fromInteger b* (v :: Vec Integer), testProperty "commutative scalar product." $ \a b v -> fromInteger (a*b)*v == fromInteger a* (fromInteger b* (v :: Vec Integer)), testProperty "inner product is zero for perpendicular vector." $ \x y -> Vec x 0 0 ・ Vec 0 y 0 == (0::Integer), testProperty "outer product is zero for parallel vector." $ \x1 x2 -> Vec x1 0 0 × Vec x2 0 0 == (0::Vec Integer) ] main :: IO () main = defaultMain tests ================================================ FILE: exercise-6-1-data-Vec/vec.cabal ================================================ name: vec version: 0.1.0.0 synopsis: Initial project template from stack description: Please see README.md homepage: http://github.com/nushio3/vec#readme license: BSD3 license-file: LICENSE author: Takayuki Muranushi maintainer: muranushi@gmail.com copyright: 2010 Author Here category: Web build-type: Simple -- extra-source-files: cabal-version: >=1.10 library hs-source-dirs: src exposed-modules: Data.Vec build-depends: base >= 4.7 && < 5 default-language: Haskell2010 executable use-vector hs-source-dirs: app main-is: Main.hs ghc-options: -threaded -rtsopts -with-rtsopts=-N build-depends: base , vec default-language: Haskell2010 test-suite vec-test type: exitcode-stdio-1.0 hs-source-dirs: test main-is: Spec.hs build-depends: base , vec , test-framework , test-framework-quickcheck2 , QuickCheck ghc-options: -threaded -rtsopts -with-rtsopts=-N default-language: Haskell2010 source-repository head type: git location: https://github.com/nushio3/vec ================================================ FILE: exercise-7-nabe/LICENSE ================================================ Copyright Takayuki Muranushi (c) 2015 All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Takayuki Muranushi nor the names of other contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================ FILE: exercise-7-nabe/Setup.hs ================================================ import Distribution.Simple main = defaultMain ================================================ FILE: exercise-7-nabe/TASK.md ================================================ # exercise 7. 鍋サーバー 次のような手順で、鍋サーバープログラムを完成させて下さい。Data.Mapを操作するのに必要な関数は、すべて以下のマニュアルのどこかにあるはずです。 https://hackage.haskell.org/package/containers-0.5.7.1/docs/Data-Map-Lazy.html 1. "recipe.txt" から具材の名前と数を読み取り、 [(String, Int)] 型の値を作ります。 2. guzaiがnabeに入っていたらその具材の個数を1減らす、guzaiの個数がゼロになったらその項目をMapから消す、 ように、関数eatを追記してください。 3. 鍋が空になったかどうかを判定する式を書いてください。 ================================================ FILE: exercise-7-nabe/nabe.cabal ================================================ name: nabe version: 0.1.0.0 synopsis: Simple project template from stack description: Please see README.md homepage: http://github.com/nushio3/nabe#readme license: BSD3 license-file: LICENSE author: Takayuki Muranushi maintainer: muranushi@gmail.com copyright: 2010 Author Here category: Web build-type: Simple cabal-version: >=1.10 executable nabe hs-source-dirs: src main-is: Main.hs default-language: Haskell2010 build-depends: base >= 4.7 && < 5 , containers ================================================ FILE: exercise-7-nabe/recipe.txt ================================================ tebamoto 3 hakusai 4 ninjin 2 shiitake 2 tofu 2 ================================================ FILE: exercise-7-nabe/src/Main.hs ================================================ module Main where import qualified Data.Map as M -- guzaiがnabeに入っていたらその具材の個数を1減らす、 -- guzaiの個数がゼロになったらその項目をMapから消す、 -- ように、関数eatを追記してください。 eat :: String -> M.Map String Int -> M.Map String Int eat guzai nabe = nabe party :: M.Map String Int -> IO () party nabe = do putStrLn $ "Nabe: " ++ show nabe order <- getLine let newNabe = eat order nabe if False -- ここで、鍋が空(null)かどうかを判定してください。 then putStrLn "The party is over!" else party newNabe readRecipe :: IO (M.Map String Int) readRecipe = do content <- readFile "recipe.txt" -- content の内容を解釈して、おいしそうな鍋の中身を作ってください! return $ M.fromList [("Kuuki",1)] main :: IO () main = do initialNabe <- readRecipe party initialNabe ================================================ FILE: exercise-7-nabe/stack.yaml ================================================ # For more information, see: https://github.com/commercialhaskell/stack/blob/release/doc/yaml_configuration.md # Specifies the GHC version and set of packages available (e.g., lts-3.5, nightly-2015-09-21, ghc-7.10.2) resolver: lts-5.0 # Local packages, usually specified by relative directory name packages: - '.' # Packages to be pulled from upstream that are not in the resolver (e.g., acme-missiles-0.3) extra-deps: [] # Override default flag values for local packages and extra-deps flags: {} # Extra package databases containing global packages extra-package-dbs: [] # Control whether we use the GHC we find on the path # system-ghc: true # Require a specific version of stack, using version ranges # require-stack-version: -any # Default # require-stack-version: >= 0.1.4.0 # Override the architecture used by stack, especially useful on Windows # arch: i386 # arch: x86_64 # Extra directories used by stack for building # extra-include-dirs: [/path/to/dir] # extra-lib-dirs: [/path/to/dir] ================================================ FILE: exercise-8-1-safe-pred/LICENSE ================================================ Copyright Takayuki Muranushi (c) 2015 All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Takayuki Muranushi nor the names of other contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================ FILE: exercise-8-1-safe-pred/Setup.hs ================================================ import Distribution.Simple main = defaultMain ================================================ FILE: exercise-8-1-safe-pred/TASK.md ================================================ # Exercise 8-1. safe pred pred :: Enum a => a -> aは危険な部分関数です。 ``` > pred True False > pred False *** Exception: Prelude.Enum.Bool.pred: bad argument > ``` 安全なpred関数 `predMay :: Enum a => a -> Maybe a` を用意しましたので、これを使って、ある値の「3つ前の値」、「n個前の値」を求める関数を作ってください。 `pred3 :: Enum a => a -> Maybe a` `predN :: Enum a => Int -> a -> Maybe a` ================================================ FILE: exercise-8-1-safe-pred/safe-pred.cabal ================================================ name: safe-pred version: 0.1.0.0 synopsis: Simple project template from stack description: Please see README.md homepage: http://github.com/nushio3/safe-pred#readme license: BSD3 license-file: LICENSE author: Takayuki Muranushi maintainer: muranushi@gmail.com copyright: 2010 Author Here category: Web build-type: Simple cabal-version: >=1.10 executable safe-pred hs-source-dirs: src main-is: Main.hs default-language: Haskell2010 build-depends: base >= 4.7 && < 5 , deepseq , spoon ================================================ FILE: exercise-8-1-safe-pred/src/Main.hs ================================================ module Main where import Control.Spoon (spoon) import Control.DeepSeq (NFData) predMay :: (Enum a, NFData a) => a -> Maybe a predMay = spoon . pred pred3 :: (Enum a, NFData a) => a -> Maybe a pred3 = undefined predN :: (Enum a, NFData a) => Int -> a -> Maybe a predN 0 x = Just x main :: IO () main = do putStrLn "hello world" print $ pred3 True print $ predN 256 'a' print $ predN 32 'z' ================================================ FILE: exercise-8-1-safe-pred/stack.yaml ================================================ # For more information, see: https://github.com/commercialhaskell/stack/blob/release/doc/yaml_configuration.md # Specifies the GHC version and set of packages available (e.g., lts-3.5, nightly-2015-09-21, ghc-7.10.2) resolver: lts-5.0 # Local packages, usually specified by relative directory name packages: - '.' # Packages to be pulled from upstream that are not in the resolver (e.g., acme-missiles-0.3) extra-deps: [] # Override default flag values for local packages and extra-deps flags: {} # Extra package databases containing global packages extra-package-dbs: [] # Control whether we use the GHC we find on the path # system-ghc: true # Require a specific version of stack, using version ranges # require-stack-version: -any # Default # require-stack-version: >= 0.1.4.0 # Override the architecture used by stack, especially useful on Windows # arch: i386 # arch: x86_64 # Extra directories used by stack for building # extra-include-dirs: [/path/to/dir] # extra-lib-dirs: [/path/to/dir] ================================================ FILE: exercise-8-2-learn-parser/LICENSE ================================================ Copyright Takayuki Muranushi (c) 2015 All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Takayuki Muranushi nor the names of other contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================ FILE: exercise-8-2-learn-parser/Setup.hs ================================================ import Distribution.Simple main = defaultMain ================================================ FILE: exercise-8-2-learn-parser/TASK.md ================================================ # exercise 8. 四則演算パーザー trifectaはパーザーコンビネータライブラリ(パーザーを作るための道具を提供するライブラリ)です。 src/ フォルダに、trifectaを使ういくつかのサンプルが入っています。 * src/parse-integer.hs 標準入力を1行毎に読み取り、整数を + 記号で区切った式であった場合にはその和を表示し、 それ以外の式の場合にはエラーメッセージを表示するプログラムです。 * src/parse-question.hs 標準入力から文字列を受け取り、一行ごとに、疑問文であると判定した場合は "質問ではない。" 疑問文であった場合は "質問ありがとう。"と表示するプログラムです。 * src/parse-S-expression.hs ファイル名をコマンドライン引数から受け取り、各ファイルをS式(lispのプログラムに使われている形式)としてパーズし、 構文木を表示するプログラムです。 ## 四則演算プログラム 以上を参考にしながら、parse-arithmetic.hs を完成させて下さい。 1. 四則演算を含む構文木Expr のパーザ、 arithmeticExprを完成させてください。 buildExpressionParser https://hackage.haskell.org/package/parsers/docs/Text-Parser-Expression.html#v:buildExpressionParser を解読して使うのもよし。自分で文法を考えてみるのもよいでしょう。 2. 構文木Exprを評価して数値に変える関数evalを完成させてください。 3. 以上の数式パーザー&評価機によって input-arith-(n).txt が正しく計算できるか確認してください。 ================================================ FILE: exercise-8-2-learn-parser/input-arith-1.txt ================================================ 1 4235 -9801 ================================================ FILE: exercise-8-2-learn-parser/input-arith-2.txt ================================================ 1+2 345+656 456+2764+33344+63436 ================================================ FILE: exercise-8-2-learn-parser/input-arith-3.txt ================================================ 60+7 60-7 60*7 60/7 ================================================ FILE: exercise-8-2-learn-parser/input-arith-4.txt ================================================ 1+2*3+4 30/3+60/4 100/7/3 640*480 1000-1-2-3-4 1*23+4+56/7*8+9 ================================================ FILE: exercise-8-2-learn-parser/input-arith-5.txt ================================================ 1+2*(3+4) 3000/(3+60)/4 100/(7/3) 640*480 1000-(1-2-3)-4 123-(45+67)+89 ================================================ FILE: exercise-8-2-learn-parser/learn-parser.cabal ================================================ name: learn-parser version: 0.1.0.0 synopsis: Simple project template from stack description: Please see README.md homepage: http://github.com/nushio3/learn-parser#readme license: BSD3 license-file: LICENSE author: Takayuki Muranushi maintainer: muranushi@gmail.com copyright: 2010 Author Here category: Web build-type: Simple cabal-version: >=1.10 executable parse-integer hs-source-dirs: src main-is: parse-integer.hs default-language: Haskell2010 build-depends: base >= 4.7 && < 5 , trifecta , ansi-wl-pprint executable parse-question hs-source-dirs: src main-is: parse-question.hs default-language: Haskell2010 build-depends: base >= 4.7 && < 5 , trifecta , ansi-wl-pprint executable parse-S-expression hs-source-dirs: src main-is: parse-S-expression.hs default-language: Haskell2010 build-depends: base >= 4.7 && < 5 , trifecta executable parse-arithmetic hs-source-dirs: src main-is: parse-arithmetic.hs default-language: Haskell2010 build-depends: base >= 4.7 && < 5 , trifecta , ansi-wl-pprint ================================================ FILE: exercise-8-2-learn-parser/output-arith-1.txt ================================================ 1 4235 -9801 ================================================ FILE: exercise-8-2-learn-parser/output-arith-2.txt ================================================ 3 1001 100000 ================================================ FILE: exercise-8-2-learn-parser/output-arith-3.txt ================================================ 67 53 420 8 ================================================ FILE: exercise-8-2-learn-parser/output-arith-4.txt ================================================ 11 25 4 307200 990 100 ================================================ FILE: exercise-8-2-learn-parser/output-arith-5.txt ================================================ 15 11 50 307200 1000 100 ================================================ FILE: exercise-8-2-learn-parser/src/parse-S-expression.hs ================================================ import Control.Applicative((<|>)) import Data.Char (isSpace) import Text.Trifecta import System.Environment (getArgs) data SExpr = Atom String | List [SExpr] deriving Show program :: Parser [SExpr] program = sexpr `sepEndBy` spaces sexpr :: Parser SExpr sexpr = list <|> atom atom :: Parser SExpr atom = Atom <$> some identifierChar <* spaces identifierChar :: Parser Char identifierChar = satisfy $ \c -> not (isSpace c) && c /= '(' && c /= ')' list :: Parser SExpr list = do symbol "(" ret <- many sexpr symbol ")" return $ List ret processFile :: FilePath -> IO () processFile filename = do result <- parseFromFile program filename case result of Nothing -> putStrLn "parse error." Just x -> mapM_ print x main :: IO () main = do filenames <- getArgs mapM_ processFile filenames ================================================ FILE: exercise-8-2-learn-parser/src/parse-arithmetic.hs ================================================ module Main where import Control.Monad (forM_) import Text.Trifecta import Text.Trifecta.Delta(Delta(..)) import Text.PrettyPrint.ANSI.Leijen(putDoc) data Expr = Literal Integer | Add Expr Expr | Sub Expr Expr | Mul Expr Expr | Div Expr Expr arithmeticExpr :: Parser Expr arithmeticExpr = do n <- integer x2 <- optional $ do symbol "+" arithmeticExpr case x2 of Nothing -> return $ Literal n Just x -> return $ Add (Literal n) x eval :: Expr -> Integer eval (Literal n) = n eval (Add x y) = eval x + eval y main = do con <- getContents forM_ (lines con) $ \str -> do case parseString arithmeticExpr (Columns 0 0) str of Failure doc -> do putDoc doc putStrLn "Parse error." Success expr -> print $ eval expr ================================================ FILE: exercise-8-2-learn-parser/src/parse-integer.hs ================================================ module Main where import Text.Trifecta import Text.Trifecta.Delta(Delta(..)) import Text.PrettyPrint.ANSI.Leijen(putDoc) additions :: Parser [Integer] additions = do xs <- integer `sepBy` symbol "+" eof return xs main = do str <- getLine case parseString additions (Columns 0 0) str of Failure doc -> do putDoc doc putStrLn "I can't understand this expression!" Success xs -> print $ sum xs main ================================================ FILE: exercise-8-2-learn-parser/src/parse-question.hs ================================================ module Main where import Text.Trifecta import Text.Trifecta.Delta(Delta(..)) import Text.PrettyPrint.ANSI.Leijen(putDoc) question :: Parser () question = do many $ satisfy $ (/= '?') string "?" eof main = do str <- getLine case parseString question (Columns 0 0) str of Failure doc -> do putDoc doc putStrLn "質問ではない。" Success _ -> putStrLn "質問ありがとう。" main ================================================ FILE: exercise-8-2-learn-parser/stack.yaml ================================================ # For more information, see: https://github.com/commercialhaskell/stack/blob/release/doc/yaml_configuration.md # Specifies the GHC version and set of packages available (e.g., lts-3.5, nightly-2015-09-21, ghc-7.10.2) resolver: lts-5.0 # Local packages, usually specified by relative directory name packages: - '.' # Packages to be pulled from upstream that are not in the resolver (e.g., acme-missiles-0.3) extra-deps: [] # Override default flag values for local packages and extra-deps flags: {} # Extra package databases containing global packages extra-package-dbs: [] # Control whether we use the GHC we find on the path # system-ghc: true # Require a specific version of stack, using version ranges # require-stack-version: -any # Default # require-stack-version: >= 0.1.4.0 # Override the architecture used by stack, especially useful on Windows # arch: i386 # arch: x86_64 # Extra directories used by stack for building # extra-include-dirs: [/path/to/dir] # extra-lib-dirs: [/path/to/dir] ================================================ FILE: exercise-9-traversable-Vec/LICENSE ================================================ Copyright Takayuki Muranushi (c) 2015 All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Takayuki Muranushi nor the names of other contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================ FILE: exercise-9-traversable-Vec/Setup.hs ================================================ import Distribution.Simple main = defaultMain ================================================ FILE: exercise-9-traversable-Vec/TASK.md ================================================ # exercise 9-1. 3次元ベクトルをTraversableにしよう。 Data/Vec.hs の定義のうち、exercise 6-1から流用できる部分は流用してください。 さらに、Vec型のFoldable, Traversableインスタンスを書いてみましょう。 として定義されかかっていますが、実装はまだ途中です。 1. src/Data/Vec.hs を編集して、 app/Main.hs が動くようにしてください! 2. test/Spec.hs にはこのライブラリをテストするプログラムが入っています。 `stack test` を実行して、あたなが実装したモジュール Data.Vec がテストを通ることを確認してください。 ================================================ FILE: exercise-9-traversable-Vec/app/Main.hs ================================================ module Main where import Data.Vec main :: IO () main = do let u, v :: Vec Integer v = Vec 1 2 3 u = Vec 10 10 10 print $ u + v -- Vec 11 12 13 と表示されてほしい! print $ u ・ v -- 60 と表示されてほしい! print $ u × v -- Vec (-10) 20 (-10) と表示されてほしい! -- VecはFoldableのインスタンスなので、ベクトル3成分の最大値・最小値が求められる。 print $ maximum v print $ minimum v ================================================ FILE: exercise-9-traversable-Vec/app/geometry.hs ================================================ import Data.Foldable import Data.Traversable import Data.SBV import Data.Vec instance EqSymbolic a => EqSymbolic (Vec a) where u .== v = toList u .== toList v problem :: Symbolic SBool problem = do a <- exists "a" let o :: Vec SReal o = Vec (-1) 0 0 v :: Vec SReal v = Vec 2 1 1 z = o + pure a * v return $ z ・ z .== 1 problem2 :: Symbolic SBool problem2 = do oy <- exists "oy" let o :: Vec SReal o = Vec 0 oy 0 v <- traverse exists (Vec "x" "y" "z") constrain $ v ・ v .== 1 a <- exists "a" b <- exists "b" return $ (o + pure a * v .== Vec (-1) 0 0 &&& o + pure b * v .== Vec 1 2 0) main :: IO () main = do putStrLn "Problem 1:" ret <- allSat $ problem print ret putStrLn "Problem 2:" ret <- allSat $ problem2 print ret ================================================ FILE: exercise-9-traversable-Vec/src/Data/Vec.hs ================================================ module Data.Vec where import Data.Monoid import Data.Foldable import Data.Traversable data Vec a = Vec a a a deriving (Show) instance Num a => Num (Vec a) where -- . . . . . . (・) :: Vec a -> Vec a -> a (Vec ax ay az) ・ (Vec bx by bz) = undefined (×) :: Vec a -> Vec a -> Vec a (Vec ax ay az) × (Vec bx by bz) = undefined instance Functor Vec where fmap f (Vec x y z) = undefined instance Applicative Vec where pure a = undefined (Vec ax ay az) <*> (Vec bx by bz) = undefined instance Foldable Vec where foldMap toMonoid (Vec x y z) = undefined instance Traversable Vec where sequenceA (Vec fx fy fz) = undefined ================================================ FILE: exercise-9-traversable-Vec/stack.yaml ================================================ # For more information, see: https://github.com/commercialhaskell/stack/blob/release/doc/yaml_configuration.md # Specifies the GHC version and set of packages available (e.g., lts-3.5, nightly-2015-09-21, ghc-7.10.2) resolver: lts-5.0 # Local packages, usually specified by relative directory name packages: - '.' # Packages to be pulled from upstream that are not in the resolver (e.g., acme-missiles-0.3) extra-deps: [] # Override default flag values for local packages and extra-deps flags: {} # Extra package databases containing global packages extra-package-dbs: [] # Control whether we use the GHC we find on the path # system-ghc: true # Require a specific version of stack, using version ranges # require-stack-version: -any # Default # require-stack-version: >= 0.1.4.0 # Override the architecture used by stack, especially useful on Windows # arch: i386 # arch: x86_64 # Extra directories used by stack for building # extra-include-dirs: [/path/to/dir] # extra-lib-dirs: [/path/to/dir] ================================================ FILE: exercise-9-traversable-Vec/test/Spec.hs ================================================ import Control.Applicative import Test.Framework (defaultMain, testGroup) import Test.Framework.Providers.API (Test) import Test.Framework.Providers.QuickCheck2 (testProperty) import Test.QuickCheck.Arbitrary import Data.Vec instance Arbitrary a => Arbitrary (Vec a) where arbitrary = Vec <$> arbitrary <*> arbitrary <*> arbitrary tests :: [Test] tests = [ testProperty "addition of Vec is associative." $ \u v w -> u+(v+w) == (u+v)+ (w :: Vec Integer) , testProperty "addition of Vec is commutative." $ \u v -> u+v == v + (u :: Vec Integer), testProperty "zero." $ \v -> v +0 == (v :: Vec Integer), testProperty "one." $ \v -> 1*v == (v :: Vec Integer), testProperty "negate." $ \v -> v - v == (0 :: Vec Integer), testProperty "distributive vector." $ \a u v -> fromInteger a*(u+v) ==fromInteger a*u +fromInteger a * (v :: Vec Integer), testProperty "distributive scalar." $ \a b v -> fromInteger (a+b)*v == fromInteger a*v+fromInteger b* (v :: Vec Integer), testProperty "commutative scalar product." $ \a b v -> fromInteger (a*b)*v == fromInteger a* (fromInteger b* (v :: Vec Integer)), testProperty "inner product is zero for perpendicular vector." $ \x y -> Vec x 0 0 ・ Vec 0 y 0 == (0::Integer), testProperty "outer product is zero for parallel vector." $ \x1 x2 -> Vec x1 0 0 × Vec x2 0 0 == (0::Vec Integer) ] main :: IO () main = defaultMain tests ================================================ FILE: exercise-9-traversable-Vec/vec.cabal ================================================ name: vec version: 0.1.0.0 synopsis: Initial project template from stack description: Please see README.md homepage: http://github.com/nushio3/vec#readme license: BSD3 license-file: LICENSE author: Takayuki Muranushi maintainer: muranushi@gmail.com copyright: 2010 Author Here category: Web build-type: Simple -- extra-source-files: cabal-version: >=1.10 library hs-source-dirs: src exposed-modules: Data.Vec build-depends: base >= 4.7 && < 5 default-language: Haskell2010 executable use-vector hs-source-dirs: app main-is: Main.hs ghc-options: -threaded -rtsopts -with-rtsopts=-N build-depends: base , vec default-language: Haskell2010 executable geometry hs-source-dirs: app main-is: geometry.hs ghc-options: -threaded -rtsopts -with-rtsopts=-N build-depends: base , vec , sbv default-language: Haskell2010 test-suite vec-test type: exitcode-stdio-1.0 hs-source-dirs: test main-is: Spec.hs build-depends: base , vec , test-framework , test-framework-quickcheck2 , QuickCheck ghc-options: -threaded -rtsopts -with-rtsopts=-N default-language: Haskell2010 source-repository head type: git location: https://github.com/nushio3/vec ================================================ FILE: greet-using-overloaded-string.hs ================================================ {-# LANGUAGE OverloadedStrings #-} import Data.Monoid ((<>)) import qualified Data.Text as T import qualified Data.Text.IO as T main :: IO () main = do name <- T.getLine T.putStrLn $ "Hello, " <> name putStrLn "This is String" ================================================ FILE: greet-using-string.hs ================================================ main :: IO () main = do name <- getLine putStrLn $ "Hello, " ++ name ================================================ FILE: greet-using-text.hs ================================================ import Data.Text (pack) import Data.Monoid ((<>)) import Data.Text.IO (getLine, putStrLn) import Prelude hiding (getLine, putStrLn) main :: IO () main = do name <- getLine putStrLn $ pack "Hello, " <> name ================================================ FILE: greet-winter.txt ================================================ 様、 立春とは名ばかりの寒い日が続きますが、いかがお過ごしでしょうか。 そちらは季節はずれの大雪となった聞きました。何かとご不自由なこともあるだとは存じますが、xx様方にはお身体だけはくれぐれもご自愛ください。 日々暖かさを増してはまいりましたが、寒い日もありますのでxx様方には、くれぐれもご自愛いただきますようお祈り申し上げます。 敬具 ================================================ FILE: hello-world.hs ================================================ main :: IO () main = interact $ const "Hello World!\n" ================================================ FILE: how-to-submit.txt ================================================ この授業の(最終)レポート提出方法は以下の通りです. 1. manabaシステムにログインする. https://manaba.tsukuba.ac.jp/ 2. 「ソフトウェアサイエンス特別講義E (GB27301)」という授業に 自分を登録する.この際,登録キーとして,2163426 を使ってください. 3. 「村主先生出題のレポート」というところから,ファイルを投入して ください.ファイルを1つだけ,提出できます.ファイルの形式等は 村主先生から指示があるはずです. 4. 締切は 2016/2/15 (月) 午前9:00 (日本時間) です.締切後に manaba から提出することはできません. 締切より前であれば何回でも再提出できますが,最後に提出したもののみが 生き残ります. ================================================ FILE: kazu.hs ================================================ data Count = One | Two | Three | Huh deriving (Eq, Ord, Show, Read, Enum) instance Num Count where One + One = Two One + Two = Three Two + One = Three _ + _ = Huh Three - One = Two Three - Two = One Two - One = One _ - _ = Huh One * x = x x * One = x _ * _ = Huh negate _ = Huh abs x = x signum Huh = Huh signum _ = One fromInteger 1 = One fromInteger 2 = Two fromInteger 3 = Three fromInteger _ = Huh main :: IO () main = do print $ One + One print $ One + Two print $ One + Three print $ One + 4 print $ [One ..] ================================================ FILE: monad-compose.hs ================================================ {-# LANGUAGE DeriveTraversable, DeriveFoldable, DeriveFunctor #-} import Control.Monad import Data.Traversable import Test.QuickCheck data Pair a = P a a deriving (Eq, Show, Functor, Foldable, Traversable) instance Applicative Pair where pure = return (P f g) <*> (P x y) = P (f x) (g y) instance Monad Pair where return x = P x x (P x y) >>= k = do (P x2 _) <- k x (P _ y2) <- k y return $ P x2 y2 newtype Bad a = B {unB :: (Maybe (Pair a))} -- http://stackoverflow.com/questions/13034229/concrete-example-showing-that-monads-are-not-closed-under-composition-with-proo?lq=1 join2 :: (Monad m, Monad n, Traversable n) => m (n (m (n a))) -> m (n a) join2 = fmap join . join . fmap sequence instance Monad Bad where return x = B $ Just (P x x) (B x) >>= k = B $ join2 $ (fmap $ fmap $ unB . k) x -- monad laws -- (1) join (return x) = x -- (2) join (fmap return x) = x -- (3) join (join x) = join (fmap join x) main :: IO () main = print $ P 4 2 ================================================ FILE: monad-family-tree.hs ================================================ type Hito = String parents :: Hito -> [Hito] parents x = [x++"の父", x++"の母"] senzo :: Int -> Hito -> [Hito] senzo 0 x = return x senzo n x = do y <- senzo (n-1) x parents y senzo' n x = senzo (n-1) x >>= parents main = mapM_ putStrLn $ senzo 3 "村主" ================================================ FILE: parser-sample.hs ================================================ module Main where import Control.Monad (replicateM) import Text.Trifecta import Text.Trifecta.Delta(Delta(..)) import Text.PrettyPrint.ANSI.Leijen(putDoc) int :: Parser Int int = fromInteger <$> integer n_words :: Int -> Parser [String] n_words n = replicateM n (token $ some alphaNum) grammar :: Parser () grammar = int >>= n_words >> eof main = do putStr "INPUT> " str <- getLine case parseString grammar (Columns 0 0) str of Failure doc -> do putDoc doc putStrLn "Wrong!" Success xs -> putStrLn "Correct!" main ================================================ FILE: quicktest.hs ================================================ import Test.QuickCheck bothBig :: Integer -> Integer -> Bool bothBig x y = x>=2 && y>=2 main :: IO () main = do quickCheck (\x y -> bothBig x y ==> x*y /= 7) quickCheck (\x y -> bothBig x y ==> x*y /= 8) ================================================ FILE: setup-tsukuba-2016.sh ================================================ echo 'export PATH=$PATH:$HOME/.local/stack/:$HOME/.local/bin/' >> $HOME/.bashrc echo 'export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$HOME/.local/lib/' >> $HOME/.bashrc source $HOME/.bashrc mkdir -p $HOME/.local/bin/ mkdir -p Downloads cd Downloads wget https://www.stackage.org/stack/linux-x86_64-gmp4 tar xf linux-x86_64-gmp4 cp stack-1.0.2-linux-x86_64-gmp4/stack ~/.local/bin/ stack setup wget https://github.com/Z3Prover/z3/archive/z3-4.4.1.tar.gz tar xf z3-4.4.1.tar.gz cd z3-z3-4.4.1/ ./configure --prefix=$HOME/.local/ cd build/ make mkdir -p $HOME/.local/lib/python2.6/dist-packages make install cd $HOME ================================================ FILE: tips.md ================================================ # Stackの使い方 ## インタプリタ編 `stack ghci`で、プロジェクトの`stack.yaml`に従った環境、または stackのグローバル設定ファイル`~/.stack/global-project/stack.yaml`に従った環境でインタプリタが起動する。 ### インタプリタのプロンプトを簡潔にする デフォルトの設定では、インタプリタのプロンプトにはロードされているモジュールの一覧が表示される。モジュールが多すぎると見にくくなることも。 この設定は、`:set prompt`で変更できる。 ``` ~$ stack ghci Run from outside a project, using implicit global project config Using resolver: lts-5.0 from implicit global project's config file: /home/nushio/.stack/global-project/stack.yaml Error parsing targets: The specified targets matched no packages. Perhaps you need to run 'stack init'? Warning: build failed, but optimistically launching GHCi anyway Configuring GHCi with the following packages: GHCi, version 7.10.3: http://www.haskell.org/ghc/ :? for help Ok, modules loaded: none. Prelude> Prelude> import Data.Map Prelude Data.Map> import Data.List Prelude Data.Map Data.List> import Data.Array.Storable.Internals Prelude Data.Map Data.List Data.Array.Storable.Internals> print $ 1+1 2 Prelude Data.Map Data.List Data.Array.Storable.Internals> :set prompt "> " > print $ 1+1 2 > ``` ホームフォルダの`.ghci`ファイルにghciへの入力を書いておくと、ghciを起動するたびにこれを実行してくれる。 ``` $ cat ~/.ghci :set -W -fno-warn-unused-imports :seti -XDataKinds -XPolyKinds -XTypeFamilies -XScopedTypeVariables -XGADTs -XTypeOperators -XTemplateHaskell :def x (\t -> return (":kind! " ++ t)) :set prompt "> " let myName = "Takayuki Muranushi" putStrLn "今日もHappy Hacking!" ``` ## ビルド編 ### `hello-project`という名前の新しいプロジェクトを作る ```` $ stack new hello-project simple ```` ### プロジェクトのビルド プロジェクトのフォルダに移動して`stack build` ```` $ cd hello-project $ stack build hello-project-0.1.0.0: configure Configuring hello-project-0.1.0.0... hello-project-0.1.0.0: build Preprocessing executable 'hello-project' for hello-project-0.1.0.0... [1 of 1] Compiling Main ( src/Main.hs, .stack-work/dist/x86_64-linux/Cabal-1.22.5.0/build/hello-project/hello-project-tmp/Main.o ) Linking .stack-work/dist/x86_64-linux/Cabal-1.22.5.0/build/hello-project/hello-project ... hello-project-0.1.0.0: copy/register Installing executable(s) in /home/nushio/nushiolab/practice/learn-haskell/exercise-1-hello-cat/hello-project/.stack-work/install/x86_64-linux/lts-5.0/7.10.3/bin ```` 実行ファイルは、stackが生成するバージョン固有のフォルダ(`.stack-work/install/x86_64-linux/lts-5.0/7.10.3/bin`など)に生成されます。どこに生成したかはstackが言ってくれます (`Installing executable(s) in...`) ### ビルドされたファイルの実行 `stack exec`で、stackが所在を把握している実行ファイルを実行してくれます。 ```` $ stack exec hello-project hello world ```` ### お手軽開発支援 次のようにすると、ファイルの変更を監視して繰り返しビルドしてくれる。 ```` $ stack build --file-watch ```` 別コンソールで`stack build --file-watch`を立ち上げておくとデバッグがはかどります。 ### stackが生成するファイルの構造 ```` $ tree hello-project/ hello-project/ ├── LICENSE ├── Setup.hs ├── hello-project.cabal ├── src │   └── Main.hs └── stack.yaml 1 directory, 5 files ```` ### プロジェクトで利用するライブラリの追加 ``` $ cat hello-project.cabal name: hello-project version: 0.1.0.0 synopsis: Simple project template from stack description: Please see README.md homepage: http://github.com/nushio3/hello-project#readme license: BSD3 license-file: LICENSE author: Takayuki Muranushi maintainer: muranushi@gmail.com copyright: 2010 Author Here category: Web build-type: Simple cabal-version: >=1.10 executable hello-project      -- 生成される実行ファイルの名前 hs-source-dirs: src -- 実行ファイルの所在 main-is: Main.hs -- ソースコードの名前 default-language: Haskell2010 build-depends: base >= 4.7 && < 5 , quickcheck -- 使いたいライブラリはここに追記します , text -- textを使いたい場合 , vector ``` ### テンプレートの一覧を表示する ```` $ stack templates chrisdone franklinchen ghcjs ghcjs-old-base hakyll-template hspec new-template # 最小限のライブラリ・実行ファイル・テストが揃っているテンプレート quickcheck-test-framework rubik scotty-hello-world scotty-hspec-wai servant simple # 最もシンプルな、ソースが1つのテンプレート yesod-hello-world yesod-minimal yesod-mongo yesod-mysql yesod-postgres yesod-postgres-fay yesod-simple yesod-sqlite ```` ### ネットに繋がらない!けどプロジェクトを作りたい。 ローカルに既にダウンロードされているテンプレートのファイル名を指定することができます。 ``` stack new offline-project ~/.stack/templates/simple.hsfiles ``` ================================================ FILE: typeclass.hs ================================================ data Person = Male String Int | Female String Int | Cat String Int Person class Greetable a where greet :: a -> IO () instance Greetable Person where greet (Male name _) = putStrLn $ "Hello, Mr. " ++ name greet (Female name _) = putStrLn $ "Hello, Ms. " ++ name greet (Cat name _ _) = putStrLn $ "Meow, " ++ name main :: IO () main = do greet $ Male "nushio" 32 ================================================ FILE: unsafe-io.hs ================================================ {-# LANGUAGE TypeSynonymInstances #-} import System.IO.Unsafe type Prog a = Int -> (Int, a) runProg :: Prog a -> (Int, a) runProg p = p 0 pureProgram x = (\n -> (n, x)) exec :: Prog a -> (a -> Prog b) -> Prog b exec p1 p2 = (\n -> let (n1,a1) = p1 n (n2,b1) = p2 a1 n1 in (n2,b1)) get :: Prog String get = \n -> (n+1, unsafePerformIO getLine) put :: String -> Prog () put str = \n -> (n+1, unsafePerformIO $ putStrLn str) main = print $ runProg $ put "May I have your name?" `exec` (\() -> get `exec` (\name -> put $ name ++ " Nice to meet you!")) ================================================ FILE: world-state.hs ================================================ import Control.Monad(ap,liftM) -- Input , Output type World = (String, String) newtype P a = P (World->(World,a)) runProgram :: P a -> IO () runProgram (P f) = interact (\input -> let ((_, output),_) = f (input,"") in output) inChar :: P Char inChar = P $ \(i, o) -> ((tail i, o), head i) inLine :: P String inLine = P $ \(i, o) -> let i2 = drop 1 $ dropWhile (/='\n') i line = takeWhile (/='\n') i in ((i2, o), line) outChar :: Char -> P () outChar c = P $ \(i, o) -> ((i, o ++ [c]), ()) outLine :: String -> P () outLine str = P $ \(i, o) -> ((i, o ++ str ++ "\n"), ()) instance Functor P where fmap = liftM instance Applicative P where pure = return (<*>) = ap instance Monad P where return x = P $ \(i,o) -> ((i,o), x) a >>= b = P $ \(i,o) -> let P f1 = a ((i1,o1),v1) = f1 (i,o) P f2 = b v1 ((i2,o2),v2) = f2 (i1,o1) in ((i2,o2),v2) greet :: P () greet = do outLine "May I have your name?" name <- inLine outLine $ name ++ ", Nice to meet you!" main = runProgram greet