Haskell

ぷよぷよ19連鎖

ゲーム「ぷよぷよ」で、フィールドの状態がテキストで与えられたとき、消える「ぷよ」を消して次のフィールドの状態を出力するプログラムを書け。 http://okajima.air-nifty.com/b/2011/01/2011-ffac.html この問題を見たときに、Haskellで解いてみたいと思…

ポイントフリーコンバータ

Haskell風に書かれた関数定義やラムダ式を、(.)やflipを使ったポイントフリースタイルに変換するプログラムを作ってみた。 http://kar.s206.xrea.com/js/pointfree.html 使用例1 例えばここにある問題を解かせてみる。 ポイントフリースタイル入門 - melpon…

コンビネータ版チャーチ数の加減乗除

たった1つの関数から出発して昨日やったチャーチ数の加減乗除 - MEMO:はてな支店を再現する。 最初に生成している各種コンビネータはコメントをつけているが、m=のところからは基本的に昨日と同じなので省略。 最初の関数x(Fokker版の一点基底コンビネータ)…

チャーチ数の加減乗除

型推論を無効にする方法を発見。 型推論をごまかす Y コンビネータ L の定義は、本当は L x y = x (y y) です。(y y)の部分が自己言及になって、GHC ではこの部分の型をうまく処理できません。そこで、unsafeCoerce で型推論をごまかしています。 http://d.h…

ポイントフリー

一つの値を名前に束縛せずに複数箇所で使うってどうやるんだ。Sコンビネータ的なものが用意されてる? cube = (((*).((*)<*>id))<*>id) -- \x -> x * x * x fib = (flip(if'.(< 2))1)<*>((+).fib.(-1 +)<*>fib.(-2 +)) http://d.hatena.ne.jp/nishiohirokazu…

各コンビネータに対応する関数

type Combinator Prelude Monad Applicative a -> a I x = x id ask a -> b -> a K x y = x const return pure (a -> b) -> (c -> a) -> c -> b B x y z = x (y z) (.) liftM (a -> b -> c) -> b -> a -> c C x y z = x z y flip (a -> a) -> a Y x = x (Y x…

Prologとリスト内包表記の対応関係

昨日の麻雀の待ちの問題、Prologのコードがほぼ1対1でリスト内包表記に書き換えられるような気がしたのでやってみた。 例えば、Prologでの順子の処理部(1行目)は、Haskellでは2行目のように記述できるはず。 (Prolog) tenpai(Xs, [[X,Y,Z]|Ys]) :- selec…

Haskellで書かれたOS

House - Haskell User's Operating System and Environment House is a demo of software written in Haskell, running in a standalone environment. http://programatica.cs.pdx.edu/House/ HaskellでスタンドアローンのOSが書けるとは。 どうでもいいけど…

フィールドラベル

runContは関数ではなくてフィールドラベルを選択関数として使ったものだった。 Continuation モナド newtype Cont r a = Cont { runCont :: ((a -> r) -> r) } -- r は計算全体の最終の型 http://www.sampou.org/haskell/a-a-monads/html/contmonad.html new…

Continuation モナド

理解するのにすごく苦労したのでメモ。 まず、定義はこんな感じ。 instance Monad (Cont r) where return a = Cont $ \k -> k a -- i.e. return a = \k -> k a (Cont c) >>= f = Cont $ \k -> c (\a -> runCont (f a) k) -- i.e. c >>= f = \k -> c (\a -> f…

Gofer

Gofer Haskellの教育的バージョン。 GoferはMark Jonesにより開発された。これはHugsに取って代わられた。 http://ja.wikipedia.org/wiki/Haskell 単なる教育用の簡易版かと思っていたら、かなり先進的なプロジェクトだったんじゃないか。 HugsのgもGoferのg…

Haskell版ハイパー演算子

なんとなく、カリー化と演算子化に対応した言語で書きたくなったので。 hyper 0 a b = succ b hyper 1 a 0 = a hyper 2 a 0 = 0 hyper n a 0 = 1 hyper n a b = hyper (n-1) a $ hyper n a (b-1) inc = hyper 0 add = hyper 1 mul = hyper 2 pow = hyper 3 t…

連続した数列を範囲形式にまとめたい

仕様 * 数値は、半角スペースで区切られた文字列で渡されます。 * 続いている部分は、最初の数値と最後の数値を-(ハイフン)で繋いだ表記にします。 * 連続が1回の場合(前の数も後ろの数も連続でない)は、-(ハイフン)では繋ぎません。 * 出力は、「,」(カンマ…

リスト内包表記の舞台裏2

以下のリスト内包表記が実際にはどう動いているのかを確認する。 [x|x<-[1..9],x<5]内包表記をdo記法に変形 do x<-[1..9]; guard(x<5); return xdo記法を >>= 演算子に変形 [1..9]>>=(\x-> guard(x<5)>>=(\_-> return x))guard を if に変形 [1..9]>>=(\x-> …

repeat,cycle,iterate

repeat,cycle,iterateでrepeat,cycle,iterateを定義してみる --repで定義したrep rep x = x : rep x --cycで定義したrep rep_cyc x = cyc [x] --iterで定義したrep rep_iter = iter id --cycで定義したcyc cyc xs = xs ++ cyc xs --repで定義したcyc cyc_rep…

リスト内包表記の舞台裏

以下のリスト内包表記が実際にはどう動いているのかを確認する。 [ (x,y) | x<-[1..3], y<-[1..3] ]内包表記をdo記法に変形 do x<-[1..3]; y<-[1..3]; return(x,y)do記法を>>=演算子に変形 [1..3]>>=(\x-> [1..3]>>=(\y-> return(x,y)))m>>=f を concatMap f…

空リストのエラー

haskellの型でハマった事例その3 main = print []これを実行すると以下のようなエラーになる。 Ambiguous type variable `a' in the constraint: `Show a' arising from use of `print' at a.hs:1:7-11 Probable fix: add a type signature that fixes these…

順列

とりあえず3個の要素決めうちバージョン perm xs = [ [a,b,c] | a<-xs, b<-xs, c<-xs, a/=b, b/=c, c/=a ] main = print $ perm [1..3]実行結果 [ [1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1] ]うーん、これをどうやって3個以外の場合に一般化すればい…

基本アルゴリズム

プログラマーでなくても名前ぐらい覚えておきたいアルゴリズムx10 http://blog.livedoor.jp/dankogai/archives/50957658.html というわけで勉強のために最初の方のを書いてみた。 といってもあまりにも有名すぎて、自分で考えて書いているというよりはどこか…

foldrとfoldl

両者の違いを実感するために、それぞれでmap関数を書いてみた。 mpr f = foldr (\a b->f a:b) [] mpl f = foldl (\a b->a++[f b]) [] main = do print $ map (*2) [1..3] print $ mpr (*2) [1..3] print $ mpl (*2) [1..3]別解 mpr f = foldr ((:).f) []

foldの呼び出し順を括弧で表示

(あるいはHaskellの型が邪魔だった事例)以下のRubyの処理をHaskellでやることを考える irb> [1,2,3].inject(0){|a,b|[a,b]} => [[[0, 1], 2], 3]まずは素直にリストでやってみる。 Prelude> foldl (\a b->[a,b]) 0 [1,2,3] Occurs check: cannot construct t…

式評価モード

なんでないのかと思っていた-eオプションはrunghcコマンドではなくghcコマンドの方にあったとは。 % ghc -e '1+1' 2 % ghc -e 'Control.Monad.Fix.fix (\f n -> if n==0 then 1 else n * f (n-1)) 4' 24goshの-u、rubyの-rのような指定したモジュールをimpor…

Control.Monad.Fix

ここにfixという名前でYコンビネータがあった。 以下は4の階乗を求める例。 import Control.Monad.Fix main = print $ fix (\f n -> if n==0 then 1 else n * f (n-1)) 4

ARGF

RubyのARGFと似たようなことを、Haskellでやってみる。 module ARGF where import System.Environment withARGF thunk = do args <- getArgs case args of [] -> getContents >>= thunk _ -> mapM_ (\f -> readFile f >>= thunk) argsARGF.hsとして保存。 こ…

1文字の二項演算子で空いているもの

% cat >t.hs main = putStr $ unlines [":t ("++[c]++")"|c<-['!'..'~']] % runghc t.hs | head 1 :t (!) % runghc t.hs | ghci 2>&1 | grep 'scope: `[^A-Za-z]' <interactive>:1:0: Not in scope: `!' <interactive>:1:0: Not in scope: `#' <interactive>:1:0: Not in scope: `%' <interactive>:1:0: Not in sc</interactive></interactive></interactive></interactive>…