Hatena::Grouphaskell

猫とC#について書く代わりにHaskellとF#について書くmatarilloの日記 このページをアンテナに追加 RSSフィード

2017-03-11

情報隠蔽とモジュールとシグネチャファイル (F# Advent Calendar 2016)

| 09:49 | 情報隠蔽とモジュールとシグネチャファイル (F# Advent Calendar 2016) - 猫とC#について書く代わりにHaskellとF#について書くmatarilloの日記 のブックマークコメント

いまさらですが、2016年12月のF# Advent Calendar記事の締め切りに間に合わなかったこともあり、アクセス数が少ないので、ここで再紹介します。

情報隠蔽とモジュールとシグネチャファイル ?オフラインリアルタイムどう書くE04? - Qiita

シグネチャファイルを書くことで、型の実装を隠蔽する方法について書きました。

……といいつつ、記事のほとんどは、横浜へなちょこプログラミング勉強会さんによるコーディング問題

五角形の世界であなたは過去の自分に出会う 横へな2016.10.30 問題

の回答になっています。 ^^

コードの説明というより、解法の説明が長いです。

2016-09-06

もしミスチルがF#だったら

| 23:49 | もしミスチルがF#だったら - 猫とC#について書く代わりにHaskellとF#について書くmatarilloの日記 のブックマークコメント

love : 'Ego -> 'Ego -> seq<int> when 'Ego : comparison

記念に。

2015-12-09

多相リテラルはないけど、演算子オーバーロードとユーザ定義型変換とカスタム数値リテラルとジェネリック単位元と

| 23:00 | 多相リテラルはないけど、演算子オーバーロードとユーザ定義型変換とカスタム数値リテラルとジェネリック単位元と - 猫とC#について書く代わりにHaskellとF#について書くmatarilloの日記 のブックマークコメント

この記事はF# Advent Calendar 2015の9日目の記事です。

記事の発端は、id:m-hiyama さんの3つの記事です。

お手軽で実用的なジェネリックスへの道は遠い - 檜山正幸のキマイラ飼育記

コンピュータは「掛け算は足し算とする」を理解できるか - 檜山正幸のキマイラ飼育記

ハイコンテキストな定数・記号の解釈 - 檜山正幸のキマイラ飼育記

3行で無理やりまとめると

  • ジェネリクスと演算子オーバーロードと型クラスが便利に使えたらいいなあ。
  • C++には演算子オーバーロードがあるし、暗黙の型変換も便利だけど、ユーザー定義リテラルはいまいち。
  • 空気を読んでくれる、多相的な定数(数値リテラル)や記号(演算子)があるともっといいのに。

2つ目の記事は、Min-Plus半環という、和と積の定義がちょっとおもしろい代数をネタにしています。

F# は

ジェネリクスある
演算子オーバーロードある
型クラスない
ユーザー定義リテラルある
暗黙の型変換ない(明示的にしかできない)
多相的な数値リテラルない

なのだけど、Min-Plus半環のコードを書いてみたらどうなるの?というのをやってみました。

まずは、m-hiyamaさんの2番目の記事のコードを参考に

  • 演算子オーバーロード
  • ユーザー定義リテラル
  • 明示的な型変換

を入れてみたのが、12/7の記事に載せたコードです。ここに再掲します。

次に、m-hiyamaさんの3番目の記事を参考にして、多相的な数値リテラルはないけれども演算子オーバーロードをたくさん作ってみたらどんな使い勝手になるかを試してみました。

簡単に解説します。

  • 演算子 @+@*がMin-Plus半環のための演算子です。これは(?<-演算子を使うハックによって)int型、float型、およびMinPlusカスタム型を引数にとることができます。
    • なお、このハックについては、この記事から始まる5つのエントリーで解説していますので、興味がある人はそちらを読んでください。
  • main関数では、シャドーイング機能を使って、+演算子*演算子の実装を@+@*に付け替えています。

ちなみに、fstropicalモジュール(fstropical.fs)では、Min-Plus半環のための演算子として@+@*を使っていますが、ここを+*に置き換えることもできます。すると、fstropicalモジュールをopenするだけで、ファイル全体で+演算子*演算子の動きが置き換わります。

m-hiyamaさんは

僕が名前(記号やリテラルも含む)のオーバーロードに拘るのは、名前の増加に耐えられないからです。

と書いていましたから、@+@*を使わないコードの方を好まれるかもしれませんね。

というわけで、「空気を読んでくれる演算子」ぐらいならF#でなんとか実現できそう、という感じでした。

2015-12-07

演算子オーバーロードとユーザ定義型変換とカスタム数値リテラルとジェネリック単位元と

| 19:57 | 演算子オーバーロードとユーザ定義型変換とカスタム数値リテラルとジェネリック単位元と - 猫とC#について書く代わりにHaskellとF#について書くmatarilloの日記 のブックマークコメント

(12/8追記: 檜山さんの新しい記事を受けて、別バージョンを書きました。https://gist.github.com/matarillo/d9861bcce64b4b6ae4da 明日には新しいブログエントリーを書くつもりです。)


Re: コンピュータは「掛け算は足し算とする」を理解できるか - 猫とC#について書く代わりにHaskellとF#について書くmatarilloの日記 - haskellの続き。

もともとの コンピュータは「掛け算は足し算とする」を理解できるか - 檜山正幸のキマイラ飼育記に近しいコードに書き直しました。

Qをプリフィックスとするカスタム数値リテラルを定義してみました。

0Q1Qの扱いをどうするか悩みましたが、実数 0.0および1.0からの変換と同じ扱いにしました。

MinPlus半環の単位元が必要な場合は、MinPlus.ZeroおよびMinPlus.Oneを使う想定です。

この2つが定義されているので、LanguagePrimitives.GenericZeroLanguagePrimitives.GenericOneを使うこともできます。といってもインライン関数以外で使ってもそんなにうれしくないですが……

2015-12-02

Re: コンピュータは「掛け算は足し算とする」を理解できるか

| 12:36 | Re: コンピュータは「掛け算は足し算とする」を理解できるか - 猫とC#について書く代わりにHaskellとF#について書くmatarilloの日記 のブックマークコメント

行列計算はともかくとして、min-plus半環そのものを定義します。

コンピュータは「掛け算は足し算とする」を理解できるか - 檜山正幸のキマイラ飼育記

複数のプリミティブ数値型に対応するには?と読みました。

新しい演算子、たとえば ?+?* を作る方法も考えられますが、まずはジェネリクスで対応。

F#には型クラスがないので、型に応じた計算の関数を引き渡してるのがださいけど、まあ大目に見るとして。


実行結果はIdeoneで見れます

もとの記事のソースをよく読むと、内部的にはdoubleだけでOKだったっぽい。そしたらもっと楽ですね。後で書けたら書く。