Polynomialを整形して表示する
Math.Polynomial
パッケージのPoly
型のShow
は内部構造をそのまま文字列表現するので、読みにくいときがあります。そこで、多項式を数式のように表示するサンプルを書いてみました。
Tabularのインストール
dein
の設定ファイルにtabular
のリポジトリを追加します。
- 設定ファイルの場所
~/.dein.toml
- 設定内容
[[plugins]] repo = 'godlygeek/tabular'
- 使い方
ビジュアルモードで範囲を指定して下記コマンドを実行します。(範囲指定は必要ないはずなのですが、範囲指定しないとタブ化できませんでした。)
:Tabularize /,
実行前
aaaa, bbbb c,d
実行後
aaaa , bbbb c , d
DeriveFoldableの練習
Foldable
であるにはFunctor
であることが前提です。そのため、Deriving
の対象となるのは、型の最後のパラメータになります。
Record syntaxを使うときに設定しておくと便利な言語拡張
Record syntax
を使うときに設定しておくと便利な言語拡張
DuplicateRecordFields
フィールド名の重複を許す。ただし、曖昧になる場合はエラーになる。
Prelude> :set -XDuplicateRecordFields Prelude> data Foo = Foo {x :: Int} Prelude> data Bar = Bar {x :: Char} Prelude> :t Foo Foo :: Int -> Foo Prelude> :t Bar Bar :: Char -> Bar -- ambiguous Prelude> :t x <interactive>:1:1: error: Ambiguous occurrence ‘x’ It could refer to either the field ‘x’, defined at <interactive>:2:17 or the field ‘x’, defined at <interactive>:3:17 Prelude> let f = Foo {x=1} Prelude> let b = Bar {x='a'} -- function application Prelude> x f <interactive>:10:1: error: Ambiguous occurrence ‘x’ It could refer to either the field ‘x’, defined at <interactive>:2:17 or the field ‘x’, defined at <interactive>:3:17 Prelude> let z = x f :: Int <interactive>:12:9: error: Ambiguous occurrence ‘x’ It could refer to either the field ‘x’, defined at <interactive>:2:17 or the field ‘x’, defined at <interactive>:3:17 Prelude> x (f :: Foo) 1 Prelude> x (b :: Bar) 'a' Prelude> Prelude> (\(Foo {x=t}) -> print t) f 1 Prelude> (\(Bar {x=t}) -> print t) b 'a' Prelude> -- record update Prelude> f' = f {x=2} <interactive>:23:6: error: • Record update is ambiguous, and requires a type signature • In the expression: f {x = 2} In an equation for ‘f'’: f' = f {x = 2} Prelude> let f' = f {x=2} :: Foo Prelude> :t f' f' :: Foo Prelude> x (f' :: Foo) 2 Prelude>
NamedFieldPuns
フィールド名の省略
Prelude> :set -XNamedFieldPuns Prelude> data Buzz = Buzz { a :: Int ,b :: Char} deriving Show Prelude> data Buzz = Buzz { a :: Integer ,b :: Char} deriving Show Prelude> Buzz 11 'x' Buzz {a = 11, b = 'x'} Prelude> (\Buzz {a,b} -> print $ (show a) ++ " " ++ (show b) ) $ Buzz 11 'x' "11 'x'"
RecordWildCards
フィールド名のワイルドカード。これを指定しておけばNameFieldPuns
は不要そうな感じ。
Prelude> :set -XRecordWildCards Prelude> (\Buzz {..} -> print $ (show a) ++ " " ++ (show b) ) $ Buzz 11 'x' "11 'x'"
cabalでのtest実行
ライブラリのテストを実行しようとしたらそのままではテストが実行できませんでした。
Servant-Server
をgit clone
して、cabal test
したら依存関係ライブラリがないと指摘されます。
(root)bar:servant-server foo$ cabal test Re-configuring with test suites enabled. If this fails, please run configure manually. Resolving dependencies... Warning: solver failed to find a solution: Could not resolve dependencies: rejecting: servant-server-0.10:!test (constraint from config file, command line flag, or user target requires opposite flag selection) trying: servant-server-0.10:*test unknown package: filemanip (dependency of servant-server-0.10:*test) Dependency tree exhaustively searched. Trying configure anyway. Configuring servant-server-0.10... setup: Encountered missing dependencies: QuickCheck -any, directory -any, doctest -any, filemanip -any, hspec ==2.*, hspec-wai ==0.8.*, parsec -any, should-not-typecheck ==2.1.*, temporary -any, wai-extra -any
servant-server.cabal
を確認すると下記のように記述されています。
test-suite spec type: exitcode-stdio-1.0 ghc-options: -Wall default-language: Haskell2010 hs-source-dirs: test main-is: Spec.hs other-modules: Servant.ArbitraryMonadServerSpec Servant.Server.ErrorSpec Servant.Server.Internal.ContextSpec Servant.Server.Internal.RoutingApplicationSpec Servant.Server.RouterSpec Servant.Server.StreamingSpec Servant.Server.UsingContextSpec Servant.Server.UsingContextSpec.TestCombinators Servant.ServerSpec Servant.Utils.StaticFilesSpec build-depends: base == 4.* , base-compat , aeson , base64-bytestring , bytestring , directory , exceptions , hspec == 2.* , hspec-wai >= 0.8 && <0.9 , http-types , mtl , network >= 2.6 , parsec , QuickCheck , resourcet , safe , servant , servant-server , should-not-typecheck == 2.1.* , string-conversions , temporary , text , transformers , transformers-compat , wai , wai-extra , warp
テスト関係のライブラリを取り込むには、--enable-test
の他に--only-dependencies
が必要です。
下記が参考になりました。
cabal - installing test dependencies
(root)bar:servant-server foo$ cabal install --only-dependencies --enable-test Resolving dependencies... Notice: installing into a sandbox located at /Users/foo/work03/webapp/servant03/src_servant/servant/servant-server/.cabal-sandbox Downloading call-stack-0.1.0... Downloading code-page-0.1.3... Configuring ghc-paths-0.1.0.9... Configuring temporary-1.2.0.4... Configuring tf-random-0.5... Configuring code-page-0.1.3... Downloading filemanip-0.3.6.3... Downloading hspec-discover-2.4.3... Downloading setenv-0.1.1.3... Downloading syb-0.7... Building temporary-1.2.0.4... Building tf-random-0.5... Building code-page-0.1.3... Installed code-page-0.1.3 Configuring call-stack-0.1.0... Building call-stack-0.1.0... Building ghc-paths-0.1.0.9... Configuring filemanip-0.3.6.3... Installed temporary-1.2.0.4 Configuring setenv-0.1.1.3... Installed ghc-paths-0.1.0.9 Building filemanip-0.3.6.3... Building setenv-0.1.1.3... Configuring hspec-discover-2.4.3... Installed call-stack-0.1.0 Downloading HUnit-1.6.0.0... Building hspec-discover-2.4.3... Configuring syb-0.7... Installed setenv-0.1.1.3 Building syb-0.7... Configuring HUnit-1.6.0.0... Installed tf-random-0.5 Building HUnit-1.6.0.0... Configuring QuickCheck-2.9.2... Installed filemanip-0.3.6.3 Installed hspec-discover-2.4.3 Building QuickCheck-2.9.2... Installed HUnit-1.6.0.0 Downloading hspec-expectations-0.8.2... Downloading should-not-typecheck-2.1.0... Configuring hspec-expectations-0.8.2... Installed syb-0.7 Downloading doctest-0.11.2... Configuring should-not-typecheck-2.1.0... Configuring doctest-0.11.2... Building hspec-expectations-0.8.2... Building should-not-typecheck-2.1.0... Building doctest-0.11.2... Installed should-not-typecheck-2.1.0 Installed hspec-expectations-0.8.2 Installed doctest-0.11.2 Installed QuickCheck-2.9.2 Downloading quickcheck-io-0.1.4... Configuring quickcheck-io-0.1.4... Building quickcheck-io-0.1.4... Installed quickcheck-io-0.1.4 Downloading hspec-core-2.4.3... Configuring hspec-core-2.4.3... Building hspec-core-2.4.3... Installed hspec-core-2.4.3 Downloading hspec-2.4.3... Downloading hspec-wai-0.8.0... Configuring hspec-2.4.3... Configuring hspec-wai-0.8.0... Building hspec-2.4.3... Building hspec-wai-0.8.0... Installed hspec-2.4.3 Installed hspec-wai-0.8.0 Updating documentation index /Users/foo/work03/webapp/servant03/src_servant/servant/servant-server/.cabal-sandbox/share/doc/x86_64-osx-ghc-8.0.1/index.html
これでcabal test
でテストが実行されます。
(root)bar:servant-server foo$ cabal test Package has never been configured. Configuring with default flags. If this fails, please run configure manually. Resolving dependencies... [1 of 1] Compiling Main ( dist/setup/setup.hs, dist/setup/Main.o ) Linking ./dist/setup/setup ... Configuring servant-server-0.10... Preprocessing library servant-server-0.10... [ 1 of 11] Compiling Servant.Server.Internal.ServantErr ( src/Servant/Server/Internal/ServantErr.hs, dist/build/Servant/Server/Internal/ServantErr.o ) [ 2 of 11] Compiling Servant.Server.Internal.Handler ( src/Servant/Server/Internal/Handler.hs, dist/build/Servant/Server/Internal/Handler.o ) [ 3 of 11] Compiling Servant.Server.Internal.RoutingApplication ( src/Servant/Server/Internal/RoutingApplication.hs, dist/build/Servant/Server/Internal/RoutingApplication.o ) [ 4 of 11] Compiling Servant.Server.Internal.Router ( src/Servant/Server/Internal/Router.hs, dist/build/Servant/Server/Internal/Router.o ) [ 5 of 11] Compiling Servant.Server.Internal.Context ( src/Servant/Server/Internal/Context.hs, dist/build/Servant/Server/Internal/Context.o ) [ 6 of 11] Compiling Servant.Server.Internal.BasicAuth ( src/Servant/Server/Internal/BasicAuth.hs, dist/build/Servant/Server/Internal/BasicAuth.o ) [ 7 of 11] Compiling Servant.Server.Internal ( src/Servant/Server/Internal.hs, dist/build/Servant/Server/Internal.o ) [ 8 of 11] Compiling Servant.Server ( src/Servant/Server.hs, dist/build/Servant/Server.o ) [ 9 of 11] Compiling Servant.Utils.StaticFiles ( src/Servant/Utils/StaticFiles.hs, dist/build/Servant/Utils/StaticFiles.o ) [10 of 11] Compiling Servant ( src/Servant.hs, dist/build/Servant.o ) [11 of 11] Compiling Servant.Server.Experimental.Auth ( src/Servant/Server/Experimental/Auth.hs, dist/build/Servant/Server/Experimental/Auth.o ) [ 1 of 11] Compiling Servant.Server.Internal.ServantErr ( src/Servant/Server/Internal/ServantErr.hs, dist/build/Servant/Server/Internal/ServantErr.p_o ) [ 2 of 11] Compiling Servant.Server.Internal.Handler ( src/Servant/Server/Internal/Handler.hs, dist/build/Servant/Server/Internal/Handler.p_o ) [ 3 of 11] Compiling Servant.Server.Internal.RoutingApplication ( src/Servant/Server/Internal/RoutingApplication.hs, dist/build/Servant/Server/Internal/RoutingApplication.p_o ) [ 4 of 11] Compiling Servant.Server.Internal.Router ( src/Servant/Server/Internal/Router.hs, dist/build/Servant/Server/Internal/Router.p_o ) [ 5 of 11] Compiling Servant.Server.Internal.Context ( src/Servant/Server/Internal/Context.hs, dist/build/Servant/Server/Internal/Context.p_o ) [ 6 of 11] Compiling Servant.Server.Internal.BasicAuth ( src/Servant/Server/Internal/BasicAuth.hs, dist/build/Servant/Server/Internal/BasicAuth.p_o ) [ 7 of 11] Compiling Servant.Server.Internal ( src/Servant/Server/Internal.hs, dist/build/Servant/Server/Internal.p_o ) [ 8 of 11] Compiling Servant.Server ( src/Servant/Server.hs, dist/build/Servant/Server.p_o ) [ 9 of 11] Compiling Servant.Utils.StaticFiles ( src/Servant/Utils/StaticFiles.hs, dist/build/Servant/Utils/StaticFiles.p_o ) [10 of 11] Compiling Servant ( src/Servant.hs, dist/build/Servant.p_o ) [11 of 11] Compiling Servant.Server.Experimental.Auth ( src/Servant/Server/Experimental/Auth.hs, dist/build/Servant/Server/Experimental/Auth.p_o ) Preprocessing test suite 'spec' for servant-server-0.10... [ 1 of 11] Compiling Servant.Server.UsingContextSpec.TestCombinators ( test/Servant/Server/UsingContextSpec/TestCombinators.hs, dist/build/spec/spec-tmp/Servant/Server/UsingContextSpec/TestCombinators.o ) [ 2 of 11] Compiling Servant.ServerSpec ( test/Servant/ServerSpec.hs, dist/build/spec/spec-tmp/Servant/ServerSpec.o ) [ 3 of 11] Compiling Servant.Utils.StaticFilesSpec ( test/Servant/Utils/StaticFilesSpec.hs, dist/build/spec/spec-tmp/Servant/Utils/StaticFilesSpec.o ) [ 4 of 11] Compiling Servant.Server.UsingContextSpec ( test/Servant/Server/UsingContextSpec.hs, dist/build/spec/spec-tmp/Servant/Server/UsingContextSpec.o ) [ 5 of 11] Compiling Servant.Server.StreamingSpec ( test/Servant/Server/StreamingSpec.hs, dist/build/spec/spec-tmp/Servant/Server/StreamingSpec.o ) [ 6 of 11] Compiling Servant.Server.RouterSpec ( test/Servant/Server/RouterSpec.hs, dist/build/spec/spec-tmp/Servant/Server/RouterSpec.o ) [ 7 of 11] Compiling Servant.Server.Internal.RoutingApplicationSpec ( test/Servant/Server/Internal/RoutingApplicationSpec.hs, dist/build/spec/spec-tmp/Servant/Server/Internal/RoutingApplicationSpec.o ) [ 8 of 11] Compiling Servant.Server.Internal.ContextSpec ( test/Servant/Server/Internal/ContextSpec.hs, dist/build/spec/spec-tmp/Servant/Server/Internal/ContextSpec.o ) test/Servant/Server/Internal/ContextSpec.hs:25:15: warning: [-Wdeferred-type-errors] • No instance for (HasContextEntry '[] Bool) arising from a use of ‘getContextEntry’ • In the expression: getContextEntry cxt :: Bool In an equation for ‘x’: x = getContextEntry cxt :: Bool In the second argument of ‘($)’, namely ‘do { let cxt = 'a' :. EmptyContext x = ...; shouldNotTypecheck x }’ test/Servant/Server/Internal/ContextSpec.hs:57:15: warning: [-Wdeferred-type-errors] • No instance for (HasContextEntry '[] (NamedContext "sub" '[Int])) arising from a use of ‘descendIntoNamedContext’ • In the expression: descendIntoNamedContext (Proxy :: Proxy "sub") cxt :: Context '[Int] In an equation for ‘x’: x = descendIntoNamedContext (Proxy :: Proxy "sub") cxt :: Context '[Int] In the second argument of ‘($)’, namely ‘do { let x = ...; shouldNotTypecheck (show x) }’ test/Servant/Server/Internal/ContextSpec.hs:61:15: warning: [-Wdeferred-type-errors] • No instance for (HasContextEntry '[] (NamedContext "foo" '[Char])) arising from a use of ‘descendIntoNamedContext’ • In the expression: descendIntoNamedContext (Proxy :: Proxy "foo") cxt :: Context '[Char] In an equation for ‘x’: x = descendIntoNamedContext (Proxy :: Proxy "foo") cxt :: Context '[Char] In the second argument of ‘($)’, namely ‘do { let x = ...; shouldNotTypecheck (show x) }’ [ 9 of 11] Compiling Servant.Server.ErrorSpec ( test/Servant/Server/ErrorSpec.hs, dist/build/spec/spec-tmp/Servant/Server/ErrorSpec.o ) [10 of 11] Compiling Servant.ArbitraryMonadServerSpec ( test/Servant/ArbitraryMonadServerSpec.hs, dist/build/spec/spec-tmp/Servant/ArbitraryMonadServerSpec.o ) [11 of 11] Compiling Main ( test/Spec.hs, dist/build/spec/spec-tmp/Main.o ) Linking dist/build/spec/spec ... Preprocessing test suite 'doctests' for servant-server-0.10... [1 of 2] Compiling Build_doctests ( dist/build/autogen/Build_doctests.hs, dist/build/doctests/doctests-tmp/Build_doctests.o ) [2 of 2] Compiling Main ( dist/build/doctests/doctests-tmp/test/doctests.hs, dist/build/doctests/doctests-tmp/Main.o ) Linking dist/build/doctests/doctests ... Running 2 test suites... Test suite spec: RUNNING... Test suite spec: PASS Test suite logged to: dist/test/servant-server-0.10-spec.log Test suite doctests: RUNNING... Test suite doctests: PASS Test suite logged to: dist/test/servant-server-0.10-doctests.log 2 of 2 test suites (2 of 2 test cases) passed. (root)bar:servant-server foo$
結果はログdist/test/servant-server-0.10-doctests.log
に出力されます。