関数型プログラミング言語Haskell Part26
■ このスレッドは過去ログ倉庫に格納されています
0147デフォルトの名無しさん
2014/09/06(土) 11:20:41.51ID:LgF+fBKU[a]やBTree aみたいなデータ構造を引数に取る関数を抽象データ型を引数に取るという手法でより一般化したいという事かね
それなら挿入・削除のような共通操作を持つ型クラスを作りってそれとFoldableを用いて実現できる
ただデータ構造によって突っ込める値に関する制約が違うというのがあるからその解決としてConstraintKindや型族みたいな言語拡張使う必要が出てきそうなのが厄介だな
操作にIOを伴うデータ型もサポートするために状態操作も抽象化したから余計面倒になったが以下のような感じで
{-# LANGUAGE ScopedTypeVariables, TypeFamilies, FlexibleContexts, ConstraintKinds #-}
import Control.Monad.State.Class
import Control.Monad.State
import qualified Data.List as L
import GHC.Exts
class RecordLike f where {
type ContentConstraint f :: * -> Constraint
; type Action f a :: * -> *
; add :: forall a. (ContentConstraint f a, MonadState (f a) (Action f a)) => a -> Action f a ()
; delete :: forall a. (ContentConstraint f a, MonadState (f a) (Action f a)) => a -> Action f a ()
}
instance RecordLike [] where {
type ContentConstraint [] = Eq
; type Action [] a = State [a]
; add a = modify $ (a:)
; delete a = modify $ L.delete a
}
これでf :: forall a. (Foldable f, RecordLike f, ContentConstraint f a) => [a] -> Action f a
みたいな形で定義すりゃその関数はリストだろうが二分木だろうがハッシュセットだろうが扱えるようになる
あとは長々と制約書くのが面倒なら型制約シノニムを使うとかで
■ このスレッドは過去ログ倉庫に格納されています