我正在遍历some Arrow tutorial,并使用函数返回自己的新版本以维持某种状态。
新类型的定义如下:
newtype Circuit a b = Circuit {runCircuit :: a -> (b, Circuit a b)}
因为我希望能够组成电路,所以将其作为Category的一个实例。组成两个电路时,结果也必须是一个电路。
(Circuit b c) . (Circuit a b)
给出Circuit a c
。我写了这个:
import qualified Control.Category as Cat
instance Cat.Category Circuit where
(Circuit g) . (Circuit f) = Circuit $ \a -> let
(b, new_f) = f a
(c, new_g) = g b
new_circ = new_g . new_f
in (c, new_circ)
但失败了:
Main.hs:70:64:
Couldn't match expected type `b0 -> c0'
with actual type `Circuit b c'
In the first argument of `(.)', namely `new_g'
In the expression: new_g . new_f
In an equation for `new_circ': new_circ = new_g . new_f
我在教程中查找了答案,这个答案引入了一个中间函数,它可以很好地编译:
(.) = dot where
(Circuit g) `dot` (Circuit f) = Circuit $ \a -> let
(b, new_f) = f a
(c, new_g) = g b
new_circ = new_g `dot` new_f
in (c, new_circ)
我看不出有什么区别。
最佳答案
.
中的new_g . new_f
来自前奏,而不是Control.Category
。因此,您需要使用Cat..
。
但是使用Control.Category
的通常方法是:
import Prelude hiding (id, (.))
import Control.Category
关于haskell - 用这种方式定义构图有什么问题?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/8787338/