一対の変換関数があるとしましょう
string2int :: String -> Maybe Int
int2string :: Int -> String
Optics を使用すると、これらをかなり簡単に表すことができます。
stringIntPrism :: Prism String Int
ただし、失敗の理由を表現したい場合は、これらを 2 つの別個の関数として保持する必要があります。
string2int :: String -> Validation [ParseError] Int
int2string :: Int -> String`
この単純な例Maybe
はまったく問題ありません。なぜなら、失敗は解析の失敗であると常に想定できるため、実際には、Either 型または Validation 型を使用してこれをエンコードする必要がないからです。
ただし、プリズムの解析に加えて、いくつかの検証を実行したいと考えてください。
isOver18 :: Int -> Validation [AgeError] Int
isUnder55 :: Int -> Validation [AgeError] Int
これらを一緒に構成できれば理想的です。
ageField = isUnder55 . isOver18 . string2Int :: ValidationPrism [e] String Int
これは手作業で構築するのはかなり簡単ですが、レンズ/光学の分野にはすでにこれを行う何かが潜んでいる可能性があるというのは十分に一般的な概念のようです。これを処理する既存の抽象化はありますか?
tl;dr
Maybe に直接結び付けるのではなく、任意のファンクターでパラメーター化できる部分的なレンズ/プリズム/アイソメを実装する標準的な方法はありますか?
上記の Haskell 記法はより単純なので使用しましたが、実際には Scala で Monocle を使用してこれを実装しています。ただし、ekmett の Lens ライブラリに固有の回答に完全に満足しています。