6
Đây là những gì tôi đã có:variadic danh sách constructor, làm thế nào để mặc định đúng loại và nhận an toàn kiểu
{-# LANGUAGE MultiParamTypeClasses
, FlexibleInstances #-}
class ListResultMult r a where
lstM :: a -> [a] -> r
listM :: ListResultMult r a => a -> r
listM a = lstM a []
instance ListResultMult r a => ListResultMult (a -> r) a where
lstM a as x = lstM x $ a:as
instance ListResultMult [a] a where
lstM a as = reverse $ a:as
Dưới đây là cách hoạt động:
> listM 'a' 'b' 'c' :: String
"abc"
> putStrLn $ listM 'a' 'b' 'c'
abc
> listM (1::Int) (2::Int) :: [Int]
[1,2]
Sau đây là cách nó không
> sum $ listM 1 2
No instance for (ListResultMult (a2 -> [a0]) a1) ...
> listM 1 :: [Int]
No instance for (ListResultMult [Int] a0) ...
Tương phản với printf:
instance Show a => ListResultMult (IO()) a where
lstM a as = print . reverse $ a:as
> listM "foo" "bar" -- boo
No instance for (ListResult t0 [Char]) ...
> printf "%s %s" "foo" "bar"
foo bar
> listM "foo" "bar" :: IO() -- yay
["foo","bar"]
Loại mất an toàn:
> :t listM 2 "foo"
Some weird type is actually inferred
Vì vậy, đây là những gì tôi muốn làm:
- Loại an toàn. Tôi nghĩ khi tôi xác định
ListResultMult r a => ListResultMult (a -> r) a
vàListResultMult [a] a
, nó sẽ chỉ cho phép bạn tạo danh sách đồng nhất và nhận thấy lỗi loại khi bạn không làm như vậy. Tại sao không? - Mặc định. Tôi không có đầu mối gì đang xảy ra với
listM 1 :: [Int]
. Có chuyện gì vậy?
Loại an toàn * và * lành mạnh mặc định! Điều này trả lời câu hỏi một cách hoàn hảo, cũng như tình cờ trả lời [câu hỏi khác của tôi] (http://stackoverflow.com/questions/8031320). :) –