きくらげ観察日記

好きなことを、適当に。

Haskell

正規表現エンジン制作入門(2): いろいろなDFA

オートマトンの単位を落としてしまいましたが、正規表現エンジンは作っていきたいと思います。前回定義したDFAを思い出してみましょう。inkar-us-i.hatenablog.comDFAは状態を持ち、入力された文字によってその状態を変えていく機械でした。この図はsが初期…

Haskellでtest/**/*Spec.hsを全部拾ってテストしてくれるやつ

よく忘れるのでメモ {-# OPTIONS_GHC -F -pgmF hspec-discover #-} test/Spec.hsにこの1行を書くだけで、test/内の全部のテストを拾い集めて実行してくれるmainを生成してくれます。 明日は正規表現エンジンのこと書きます。

正規表現エンジン制作入門(1): 正規表現とDFA

オートマトンの単位は落としそうですが、今日から数回に分けてHaskellで正規表現エンジンを自作していきたいと思います。 完成図 実は既に手元に完成品があるのですが、今回はHaskellで正規表現風DSLを構築したいと思います。動作例は以下の通り。 >>> str "…

型クラスのインスタンスが複数ある場合の話(Haskell編)

inkar-us-i.hatenablog.comこちらで出した例はScalaでしたが、Haskellでも同様の問題は起こりえます。 -- TreeSet.hs module TreeSet ( Cmp(..) , TreeSet() , empty , insert , fromList , elem ) where import Prelude hiding (elem) class Cmp a where eq…

libraryとexecutable両方を含むcabalパッケージを作る

cabal initした時に「libraryとexecutable、どっちのパッケージにする?」みたいなことを聞かれるので、今まで1つのパッケージにはlibraryとexecutableのどちらか一方しか含むことができないと思っていました。.cabalにlibrary:とexecutable:の両方を書けば…

stackでプロファイリングを有効にしてビルドする

以下のようにオプションを渡せば、stackでもプロファイリングを有効にしてビルドすることができます。 $ stack build --executable-profiling --library-profiling --ghc-options="-fprof-auto -rtsopts" あと、実行時にも1つハマりどころがあります。ビルド…

ようやくstackを使い始めた話

レポートの提出期限間際にcabalの依存関係がぶっ壊れて大変な思いをしたので、ようやく重い腰を上げてstackを使い始めてみることにしました。 インストール インストール方法とかはだいたいこの辺を参照しました。stack/install_and_upgrade.md at master · …

パターンマッチでTextを1文字ずつ処理する

PatternSynonymsのいい感じの実用例が思いついたので。 {-# LANGUAGE PatternSynonyms, OverloadedStrings, ViewPatterns #-} import Data.Text pattern c :+ cs <- (uncons -> Just (c, cs)) このパターンを定義することで、先頭文字がcで残りがcsであるよ…

ImplicitParamをConstraintとして扱う

=>の左側に来るものはすべてConstraintなので、暗黙引数をConstraintとして扱うこともできます。 {-# LANGUAGE ConstraintKinds, ImplicitParams #-} type Showable t = ?show :: t -> String print' :: Showable t => t -> IO () print' a = putStrLn $ ?sh…

Cabalで静的ファイルをパッケージに含める

YourPackage.cabalに data-dir: dirname data-files: *.txt img/*.pngのように記述すると、dirname以下のdata-filesに指定したファイルがインストール時にコピーされます。また、これらのファイルにアクセスするためのPaths_YourPackage という名前のモジュ…

型クラス自体を型として扱う

ConstraintKinds拡張を使うと、型定義の=>の左辺にくる制約そのものを型として扱うことができるようになります。 {-# LANGUAGE ConstraintKinds #-} -- ConstraintKinds拡張がなければこのような定義はできない type MyShow t = Show t -- typeで定義した制…

モナドで擬似マルチタスク

継続のことばかり考えていたらなんとなく思いついてしまったので載せておきます。 {-# LANGUAGE GADTs #-} module Concurrent where import Control.Monad import Control.Monad.IO.Class import Data.Either data ConT m b where Done :: m b -> ConT m b B…

Haskellで辞書リテラルや集合リテラルを扱う

OverloadedLists拡張を有効化すると、通常のリストリテラルの型が[a]からforall t. IsList t => tになります。IsList型クラスはGHC.Extsで定義されており、以下のような定義になっております。 class IsList l where type family Item l :: * fromList :: [I…

独自のkindを定義する

DataKinds拡張を有効にすると、独自のkindを定義することができるようになります。 data Nat = Z | S Nat 通常これは「値コンストラクタZとSからなる型Nat」が定義されますが、DataKinds拡張が有効になっている場合、この型Natと値コンストラクタZ, Sが、そ…

Haskellで独自のパターンを定義

Scalaではunapplyメソッドを定義することにより独自のパターンを定義できますが、実はHaskellでも似たようなことができます。PatternSynonyms拡張を有効化することで、既存のパターンについてのエイリアスのようなものを定義することができます。 {-# LANGUA…

Scala的な型クラスをHaskellで作る

Scalaの型クラスはHaskellの型クラスとは全くの別物ですが、HaskellでもImplicitParams拡張を使うことによってScalaの型クラスのようなものを利用できるようになります。 ImplicitParams このマイナーな拡張を有効化すると、関数に対して暗黙的に引数を渡す…

ID3アルゴリズムで決定木を生成する

機械学習の勉強として、ID3アルゴリズムにより決定木を生成するプログラムを書いてみました。ID3 - WikipediaID3アルゴリズムについて軽く説明します。例えば何らかの調査を行って得た以下のデータを分類したいとします。 名前 髪の色 身長 体重 ローション…

gunfoldの型を読み解く

まず最初に、Data型クラスのその他のメソッドについて見てみましょう。 >>> :t toConstr toConstr :: Data a => a -> Constr toConstrは、値から値コンストラクタの情報を得るための関数です。 data Dish = Sushi { fish :: String } | Curry { isChicken ::…

Data.Dataのgfoldlの型を読み解く

Data.Data.Data型クラスを使うと、Typeableと同様に非常に一般的な関数を書くことができるようになります。前回のTypeableは値の型情報を取得するだけでしたが、Dataのメソッドを用いると代数的データ型の任意のフィールドにアクセスするといったようなこと…

Typeableを使ってみる

Data.Typeable.Typeableを使うと、TemplateHaskell無しでも非常に一般的な関数を書くことができるようになります。型クラスData.Typeableのインスタンスは、typeOfという関数を使うことによって型情報を取得することができます。 >>> :m +Data.Typeable >>> …