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