2008-08-13
■ [ruby] ruby Functor gem
RubyでHaskellやOCamlのようなパターンマッチを実現しようという試みはいくつもありますが、それらの中では一番綺麗なんじゃないでしょうか(見た目的な意味で)。
fib = Functor.new do given( 0 ) { 0 } given( 1 ) { 1 } given( Integer ) { |n| self.call( n - 1 ) + self.call( n - 2 ) } end
どうでしょうか?
ところでFunctorって一体なんなんでしょう。いろんなところで名前だけは聞くのですが…。
関手(かんしゅ、functor)とは、圏論における一つの圏から別の圏への対応でその構造と両立するようなものである。関手によって一つの数学体系から別の体系へのシステマティックな対応が定式化される。関手は「圏の圏」における射と考えることもできる。
[関手 - Wikipediaより引用]
分かる要素がないwww
■ [ruby] RubyTreemap
ハードディスクの使用状況を、地図のように分かりやすく表示してくれるソフトウェアがあります。例えばSpaceMongerとか。
RubyTreemapは、このような画像を簡単に作るためのライブラリだそうです。PNG, SVGのほか、htmlでも出力できる模様。
しかし、ハードディスクの使用状況以外でどういう用途に使えるんでしょう?ツリーの各節点が何かの大きさを持つような構造といえば…。うーん、何だろう。
(追記: 例えば家計簿の支出を階層構造のカテゴリに分けると、「今月本にはこれくらい使って、そのうち漫画はこれくらい」とか分かっていいかも。)
■ [haskell] HUnitを使ってみた
(追記:Test.HUnitはGHCだと標準で入ってます。インストールは不要。)
一応AssertEqualとかもあるんですけど、そうじゃなくて演算子の方を使うのが玄人らしい。
僕はRSpecが好きなので~?= を使ってますが、 ~=?を使えば逆順 (つまり <expected> ~=? <given>) で書くこともできます。
plus3.hs:
module Plus3 where plus3 :: Int -> Int -> Int -> Int plus3 x y z = x + y + z
test_plus3.hs:
import Test.HUnit import Plus3 simpleTest = [ "plus3 should plus 3 integers" ~: (plus3 1 2 3) ~?= 6 , "plus3 should plus 3 negative integers" ~: plus3 (-1) (-2) (-3) ~?= -6 ] largeTest = [ "plus3 should plus 3 large integers" ~: (plus3 1000000000000000000000000 2000000000000000000000000 3000000000000000000000000) ~?= 6000000000000000000000000 ] testData = [ "simple" ~: simpleTest , "large data" ~: largeTest ] main = runTestTT (test testData)
実行結果:
/Users/yhara/proj/babel21/haskell % runghc test_plus3.hs Cases: 3 Tried: 3 Errors: 0 Failures: 0
MacPortsで入れたGHC 6.8.2で確認。
■ [haskell] Haskellで外部プログラムとパイプ経由でやりとりしてみた
Rubyでいうopen3である。
import System.Process import System.IO main :: IO () main = do (stdin, stdout, stderr, processHandle) <- runInteractiveCommand "sort" hPutStr stdin "foo\nbar\nbaz" result <- hGetContents stdout putStr result
どう見ても手続き型ですw 思ったより簡単だな。
実行結果:
/Users/yhara/proj/babel21/haskell % runghc process_sample.hs bar baz foo
"Introducing Functor"の"Functor"はちょっとわからなかったのですが、MLやC++のfunctorは「関数みたいだけど関数ではないもの」ぐらいの感じだと昔聞いたことがあります。数学での定義は私もよくわかっていないのですが、「関手は「圏の圏」における射と考えることもできる。」というのも、そんなような感じじゃないかと思います。
functorという言葉は、プログラミング言語界隈では圏論の関手の意味を超えてもっと広くゆるく使われてますね。<br>圏論の関手は圏から圏への写像で、何を圏とみなすかでいろいろ変わってきます。<br>HaskellのFunctorクラスは一応「型を対象とし関数を射とする圏」を写すものっぽい感じになってます。MLのfunctorは単なるモジュールからモジュールへの写像です。C++やこの例のfunctorはあまり圏論の関手を意識してつけられたネーミングではなさそうです。ほんと「関数っぽいもの」ぐらいのノリですかね。
soutaroさん、minkeさん:<br>ありがとうございます。必ずしも「Functor == 関手」の意味で使われてるわけではないのですね。<br>「Function => 関数、Functor => 関数っぽいもの」か。なるほど。