haskell-jp / questions #102

cabal.project.local に相当するような stack.yaml のやつってありますか?
... Replies ...
いくつかのデータ型があらかじめ定義されており、それらはTLV(type length value)で統一的に符号化されるとします。
これに対する符号器/復号器の基本ライブラリを作りますが、データ型は将来追加されるかもしれないので、サードパーティライブラリで拡張可能としたいです。

まず、符号化のために以下のようなクラスを定義します。

class Typeable a => T a where
  typeT  :: Int
  encode :: T -> ByteString
  decode :: ByteString -> T
  fromTLV :: TLV -> Maybe a  -- TLVは後述
  fromTLV (TLV x) = cast x
  toTLS :: a -> TLV
  toTLS = TLV

既存のデータを表す型を A と B とすると、

data A = A ...
data B = B ...

instance A where
  typeT = 0
  encode = ...
  decode = ...

instance B where
  typeT = 1
  encode = ...
  decode = ...

これらの型を同じように扱えるように、 ExistentialQuantification を用いて、以下の型を定義します。

data TLV = forall a. T a => TLV a

符号器で encode を使うのは、 a が与えられるので簡単です。

encodeTLV :: TLV -> ByteString
encodeTLV (TLV x) = encode x

問題は復号器です。TLVのTとLの部分は ByteString に符号化された整数なので、それをパースして V の部分の ByteString を切り出した後に、適切な decode を呼ぶだしたいのですが、どうすれば呼べるでしょうか?

ぱっと思いつくのは、 Int -> ByteString の辞書を用意して、それを引くことです。拡張可能にするのは、この辞書を公開し、利用時に要素を追加可能にする必要がありそうです。

基本的に reflaction に関係する問題だと思います。サードバーティが data C を定義したら、自動的にその decode も呼ばれるような魔法はあるのでしょうか?
... Replies ...
Haskellそのものとは関係ない質問になるので恐縮ですがお聞かせ下さい

プログラミング初心者やHaskellの周辺に全く触れたことない人向けに一時間程度Haskellについて話す機会を得たのですが、皆さんならどういった内容を話すと良いと思われますか?
... Replies ...
ライブラリを書いており、テスト用にライブラリ内で定義した型の QuickCheckの Arbitrary インスタンスを作成しようと考えています。 Arbitrary インスタンスをどこに書くのが良いのかで悩んでいます。
このライブラリを他のプロジェクトから使った時にも Arbitrary インスタンスを使えるようにしたいので、テストコード側ではなくライブラリ側に書きたいと考えています。
しかし、インスタンスを書く為に必要な quickcheck-instancesライブラリがそれ自身を他のライブラリの依存パッケージとしないことを推奨しているため、「ライブラリ側に書く」のを躊躇しています。
別のライブラリとして記述するという方法もあると思いますが、それだと後々整合性を持たせるのを忘れそうなのであまり使いたくないなぁと思っています。

この場合どこに書くのが適切なのでしょうか
... Replies ...
@kohei wada has joined the channel
@ has joined the channel
Motoyuki Kimura (M.Kimura)
@Motoyuki Kimura (M.Kimura) has joined the channel
はじめて質問させていただきます。
Haskell学習中の者で、理解が進まない箇所があるのでお力添えいただきたく思います:man-bowing:
(続く...)
... Replies ...
@なっつ has joined the channel
現在作ろうとしているツールの一環として、「一定の文字列候補の中から、入力された文字列に一致する文字列をフィルタリングする」機能を作ろうとしています。
(最終的に作りたいものはrofiやdmenuと似たようなものです、というか具体的にはrofiクローンのようなツールを作ろうとしています)

このツールでは「文字列の一致」の判定方法をFuzzyやGlob、regex等複数から選べるようにしたいため、ツール全体のステートを維持する型の中に判定用の関数(matcherと呼ぶことにします)を含めたいです。

実際に今考えていたのは以下のような型です:

data AppModel = AppModel { _typing :: Text
           , _candidates :: Zipper Candidate
           , _configFile :: FilePath
           , _matcher :: (T.Text -> T.Text -> Bool) -- ^ ここのこと
           } deriving (Eq)

しかし、 AppModel はUIライブラリ()の都合で Eq インスタンスを持つ必要があるのですが、 Eq (a -> a) のインスタンスが存在しない故に定義が出来なくなってしまっています。

実装の仕方を自分なりに複数考えてみたのですが、どれも微妙でどれを選ぶべきなのか、またより良い方法は無いのかで悩んでいます。
何かしら定石みたいなものがあれば教えていただければ幸いです :pray:
(自分で考えたものはスレッドに書き込みます)
... Replies ...
@arark has joined the channel