2012-01-09 23 views
6

Tôi đã trải qua some Arrow tutorial, đùa giỡn với các chức năng trả về phiên bản mới của bản thân nhằm cố gắng duy trì một số trạng thái.Có gì sai khi xác định bố cục theo cách này?

Kiểu mới được định nghĩa như thế:

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

Bởi vì tôi muốn để có thể soạn mạch tôi làm cho nó một thể hiện của loại. Khi soạn hai mạch, kết quả cũng phải là một mạch. (Circuit b c) . (Circuit a b) cho số Circuit a c.

tôi đã viết này:

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) 

nhưng nó không thành công:

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 

Tôi nhìn lên những câu trả lời trong phần hướng dẫn và câu trả lời này đã được giới thiệu một chức năng trung gian như thế này, mà biên dịch độc đáo:

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

Tôi không thấy sự khác biệt.

Trả lời

10

. trong new_g . new_f là từ khúc dạo đầu, không phải từ số Control.Category. Vì vậy, bạn cần sử dụng Cat...

Nhưng cách thông thường để sử dụng Control.Category là:

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

Perfect, thêm 'Cat.' chỉ hoạt động. Cảm ơn lời khuyên, tôi thấy bây giờ tại sao chúng tôi muốn ẩn id và (.). – Niriel

Các vấn đề liên quan