Tôi đã viết một Newtype Const3
đó là rất giống với Const
, nhưng chứa đầu tiên trong ba đối số loại nhất định:Tôi có thể triển khai loại mới này làm thành phần của các loại khác không?
newtype Const3 a b c = Const3 { getConst3 :: a }
tôi có thể xác định rất nhiều trường hợp có ích cho Newtype này, nhưng tôi sẽ phải làm nó tất cả bản thân mình.
Tuy nhiên, chức năng Tôi đang áp dụng theo mức độ loại tương tự như chức năng
\a b c -> a
mà @pl
nói với tôi là tương đương với const . const
.
Cả hai (.)
và const
khớp với trình bao bọc newtype: Compose
và Const
. Vì vậy, tôi figured tôi muốn có thể viết:
type Const3 = Compose Const Const
Và kế thừa trường hữu ích tự động, chẳng hạn như:
instance Functor (Const m)
instance (Functor f, Functor g) => Functor (Compose f g)
-- a free Functor instance for Const3!
Nhưng GHC không đồng ý:
const3.hs:5:23:
Expecting one more argument to ‘Const’
The first argument of ‘Compose’ should have kind ‘* -> *’,
but ‘Const’ has kind ‘* -> * -> *’
In the type ‘Compose Const Const’
In the type declaration for ‘Const3’
này có vẻ là có liên quan đến các loại Compose
và Const
:
*Main> :k Compose
Compose :: (* -> *) -> (* -> *) -> * -> *
*Main> :k Const
Const :: * -> * -> *
Vì vậy, sau một chút tìm kiếm, tôi phát hiện ra rằng có một phần mở rộng GHC gọi PolyKinds
cho phép tôi làm điều gì đó như:
{-# LANGUAGE PolyKinds #-}
newtype Compose f g a = Compose { getCompose :: f (g a) }
newtype Const a b = Const { getConst :: a }
Và như một phép màu các loại là đúng:
*Main> :k Compose
Compose :: (k -> *) -> (k1 -> k) -> k1 -> *
*Main> :k Const
Const :: * -> k -> *
Nhưng tôi vẫn không thể soạn chúng để viết Const3 = Compose Const Const
.
const3.hs:12:23:
Expecting one more argument to ‘Const’
The first argument of ‘Compose’ should have kind ‘* -> *’,
but ‘Const’ has kind ‘* -> k0 -> *’
In the type ‘Compose Const Const’
In the type declaration for ‘Const3’
Điều gì mang lại? Có cách nào thông minh để làm điều này, vì vậy tôi có thể gặt hái những lợi ích của việc kế thừa các trường hợp Functor
vv từ Const
và Compose
?
(Là một lưu ý phụ, ý nghĩ ban đầu mà dẫn tôi đến
Const3
đang viết:newtype Const3 a b c = Const3 { getConst3 :: a } instance Monoid m => Category (Const3 m) where id = Const3 mempty Const3 x . Const3 y = Const3 (mappend x y)
bắt ý tưởng rằng một monoid là một phạm trù đơn đối tượng Nó sẽ được tốt đẹp nếu. có một giải pháp mà vẫn cho phép tôi viết ví dụ trên bằng cách nào đó.)
'loại Const3 a b c = Soạn (một Const) (b Const) c'? Vì 'nhưng 'Const' có thông báo loại‘ * -> * -> * ’' ngụ ý, bạn cần cung cấp một kiểu cho hàm tạo kiểu để đến kiểu được mong đợi bằng 'Soạn'. – danidiaz