简体   繁体   English

以这种方式定义组合有什么问题?

[英]What's wrong with defining composition this way?

I was going through some Arrow tutorial , toying with functions returning a new version of themselves in an attempt to maintain some state. 我正在阅读一些Arrow教程 ,玩弄函数返回自己的新版本以试图维持某种状态。

The new type is defined like that: 新类型定义如下:

newtype Circuit a b = Circuit {runCircuit :: a -> (b, Circuit a b)}

Because I want to be able to compose circuits I make it an instance of Category. 因为我希望能够编写电路,所以我将它作为Category的一个实例。 When composing two circuits, the result must also be a circuit. 在组成两个电路时,结果也必须是电路。 (Circuit bc) . (Circuit ab) (Circuit bc) . (Circuit ab) gives a Circuit ac . (Circuit bc) . (Circuit ab)给出一个Circuit ac

I wrote this : 我写了这个:

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)

but it fails: 但它失败了:

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

I looked up the answer in the tutorial and this answer was introducing an intermediate function like this, which compiles nicely: 我在教程中查找了答案,这个答案引入了一个像这样的中间函数,编译得很好:

(.) = 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)

I fail to see the difference. 我没有看到差异。

The . . in new_g . new_f new_g . new_f new_g . new_f is from the prelude, not from Control.Category . new_g . new_f来自前奏,而不是来自Control.Category So you need to use Cat.. . 所以你需要使用Cat..

But the usual way to use Control.Category is: 但是使用Control.Category的常用方法是:

import Prelude hiding (id, (.))
import Control.Category

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM