2010-07-30 24 views
7

Có thể sử dụng các từ đồng nghĩa loại làm đối số của hàm tạo kiểu biến áp đơn nguyên không? Đặc biệt, nếu có một từ đồng nghĩa kiểu đơn nhất cho một biến áp đơn lẻ được áp dụng, nó có thể được sử dụng như một loại của đơn nguyên cơ bản trong một biến áp đơn nguyên khác không?Sử dụng các từ đồng nghĩa loại trong biến thế đơn lẻ

Từ những gì tôi thấy loại từ đồng nghĩa không được chấp nhận như loại hạng nhất nhà thầu, xem ví dụ và thông báo lỗi dưới đây:

-- Using type synonym of a monad transformer in another monad transformer. 

import Control.Monad.Reader 

-- inner transformer 
type A a = ReaderT Int IO a 

-- type B a = ReaderT String A a 
{- Error: 
readert2.hs:8:0: 
    Type synonym `A' should have 1 argument, but has been given 0 
    In the type synonym declaration for `B' 
-} 

-- type B a = ReaderT String (A a) a 
{- Error: 
readert2.hs:15:27: 
    Kind mis-match 
    The second argument of `ReaderT' should have kind `* -> *', 
    but `A a' has kind `*' 
    In the type `ReaderT String (A a) a' 
    In the type synonym declaration for `B' 
-} 

type B a = ReaderT String (ReaderT Int IO) a 
{- OK -} 

main = do 
    r <- flip runReaderT 39 $ do 
      n <- ask :: A Int 
      s <- flip runReaderT "foo" $ (ask :: B String) 
      return $ n + length s 
    print r 

Có cách nào để tránh việc mở rộng các loại từ đồng nghĩa A trong định nghĩa của B a ?

Trả lời

12

Không thể áp dụng một phần từ đồng nghĩa. Trong trường hợp cụ thể này, bạn có thể viết

type A = ReaderT Int IO 
type B a = ReaderT String A a 

[hoặc thậm chí tốt hơn type B = ReaderT String A sử dụng B trong một biến đơn nguyên]

Đó là nói chung, chuyển đổi đó là không thể mà không sử dụng Newtype/dữ liệu, ví dụ:

type A a = Reader a Int 

không thể viết tương đương là type A = .... Trong một số ý nghĩa, tính năng này sẽ tương đương với loại lambda \a -> Reader a Int.

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