10

Image私は基本的にフロートのC配列である型を持っています。map :: (Float -> Float) -> Image -> Image、 、などの関数を簡単に作成できますzipWith :: (Float -> Float -> Float) -> Image -> Image -> Image

ただし、これらの関数の上にアプリケーション インスタンスのように見えるものを提供することも可能であり、 や のようなより柔軟なピクセル レベルの操作が可能になると感じてい((+) <$> image1 <*> image2)ます((\x y z -> (x+y)/z) <$> i1 <*> i2 <*> i3)。ただし、Image タイプには float 以外のものを含めることができないため、単純なアプローチは失敗し、fmapそのように実装することはできません。

これはどのように実装できますか?

4

3 に答える 3

15

コメントを読んで、サイズがここのカーペットの下にあることを少し心配しています. サイズが一致しない場合の賢明な動作はありますか?

それまでの間、次の方針に沿って賢明にできることがあるかもしれません。配列をポリモーフィックにするのが簡単でない場合でも、Applicativeこのようなインスタンスを作成できます。

data ArrayLike x = MkAL {sizeOf :: Int, eltOf :: Int -> x}

instance Applicative ArrayLike where
  pure x                 = MkAL maxBound  (pure x)
  MkAL i f <*> MkAL j g  = MkAL (min i j) (f <*> g)

(熱狂的な人は、( , ) モノイド(Int ->)によって誘導されたアプリカティブの積を私が取ったことに気付くでしょう。)maxBoundmin

きれいな対応をしてもらえますか

imAL :: Image -> ArrayLike Float
alIm :: ArrayLike Float -> Image

射影と作表によって?もしそうなら、あなたはこのようなコードを書くことができます。

alIm $ (f <$> imAL a1 <*> ... <*> imAL an)

さらに、そのパターンをオーバーロードされた演算子としてラップしたい場合は、

imapp :: (Float -> ... -> Float) -> (Image -> ... -> Image)

これは、型クラス プログラミングの標準的な演習です。(さらにヒントが必要な場合は尋ねてください。)

ただし、重要な点は、ラッピング戦略により、機能的な上部構造を上に置くために配列構造をいじる必要がないということです。

于 2011-08-11T12:34:14.617 に答える
6

画像内のピクセルに対してどのように操作を実行することを期待しますか?つまり、の場合((+) <$> image1 <*> image2)、Haskellですべての操作を実行して新しい結果のイメージを作成しますか、それともすべての処理を実行するためにC関数を呼び出す必要がありますか?

前者の場合、豚肉労働者の答えは私がとるアプローチです。

代わりに、すべての画像操作をC経由で処理する必要がある場合は、操作を表す小さなDSLを作成してみてはどうでしょうか。

于 2011-08-11T13:56:28.353 に答える
6

Image「ピクセル」タイプを一般化し、Float有限および離散ドメイン(配列)から無限および連続ドメインに拡張すると、より構成的なタイプが得られます。これらの一般化のデモンストレーションとして、ペーパーFunctional Imagesと対応するサンプルイメージ(の有限サンプリング) のギャラリーを参照してください。その結果、MonoidFunctorApplicativeMonad、およびのインスタンスが得られますComonad。さらに、これらのインスタンスの意味は、関数の対応するインスタンスによって完全に決定され、セマンティック型クラス射の原則を満たします. その論文のセクション 13.2 では、画像について簡単に説明しています。

于 2011-08-14T20:08:31.003 に答える