ale*_*tor 10 haskell ffi functor applicative
我的类型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类型不能包含浮点数以外的东西,因此无法实现fmap.
怎么能实现呢?
pig*_*ker 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)
Run Code Online (Sandbox Code Playgroud)
(爱好者会注意到我已经(Int ->)使用了(maxBound,min)monoid 引起的应用产品.)
你能做一个干净的通信吗?
imAL :: Image -> ArrayLike Float
alIm :: ArrayLike Float -> Image
Run Code Online (Sandbox Code Playgroud)
通过投影和制表?如果是这样,你可以编写这样的代码.
alIm $ (f <$> imAL a1 <*> ... <*> imAL an)
Run Code Online (Sandbox Code Playgroud)
此外,如果您希望将该模式包装为重载运算符,
imapp :: (Float -> ... -> Float) -> (Image -> ... -> Image)
Run Code Online (Sandbox Code Playgroud)
它是类型类编程的标准练习!(询问您是否需要更多提示.)
但关键的一点是,包装策略意味着您不需要使用数组结构,以便将功能上层结构放在顶部.
您希望如何对图像中的像素执行操作?也就是说((+) <$> image1 <*> image2),为什么你想要在Haskell中执行所有操作并构造一个新的结果图像,还是你必须调用C函数来进行所有处理?
如果是前者,那么Pigworker的答案就是我要采取的方法.
相反,如果需要通过C处理所有图像处理,那么如何创建一个小型DSL来表示操作呢?
| 归档时间: |
|
| 查看次数: |
713 次 |
| 最近记录: |