Haskell 变量列表构造函数,如何默认为正确的类型并获得类型安全性
以下是我得到的:Haskell 变量列表构造函数,如何默认为正确的类型并获得类型安全性,haskell,type-safety,variadic-functions,Haskell,Type Safety,Variadic Functions,以下是我得到的: {-# 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 => ListResu
{-# 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
下面是它的工作原理:
> listM 'a' 'b' 'c' :: String
"abc"
> putStrLn $ listM 'a' 'b' 'c'
abc
> listM (1::Int) (2::Int) :: [Int]
[1,2]
下面是它失败的原因
> sum $ listM 1 2
No instance for (ListResultMult (a2 -> [a0]) a1) ...
> listM 1 :: [Int]
No instance for (ListResultMult [Int] a0) ...
与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"]
类型不安全:
> :t listM 2 "foo"
Some weird type is actually inferred
下面是我想做的:
- 类型安全。我想,当我定义
和listrestmult r a=>listrestmult(a->r)a
时,它只允许您建立同构列表,如果您不这样做,就会注意到一个类型错误为什么没有呢?listrestmult[a]a
- 违约。我不知道
到底发生了什么奇怪的事情怎么了?listm1::[Int]
{-# LANGUAGE TypeFamilies #-}
class ListResultMult r where
type Elem r
lstM :: Elem r -> [Elem r] -> r
listM a = lstM a []
instance (ListResultMult r, Elem r ~ a) => ListResultMult (a -> r) where
type Elem (a -> r) = a
lstM a as x = lstM x (a:as)
instance ListResultMult [a] where
type Elem [a] = a
lstM a as = reverse (a:as)
以下是您在ghci中的示例:
*Main> listM 'a' 'b' 'c' :: String
"abc"
*Main> putStrLn $ listM 'a' 'b' 'c'
abc
*Main> listM 1 2 :: [Int]
[1,2]
*Main> sum $ listM 1 2
3
*Main> listM 1 :: [Int]
[1]
*Main> :t listM 'a' True
<interactive>:1:7:
Couldn't match type `Bool' with `Char'
In the first argument of `listM', namely 'a'
In the expression: listM 'a' True
*Main> :t listM 2 "foo"
<interactive>:1:7:
No instance for (Num [Char])
arising from the literal `2'
Possible fix: add an instance declaration for (Num [Char])
In the first argument of `listM', namely `2'
In the expression: listM 2 "foo"
*Main>listma'b'c'::字符串
“abc”
*Main>putStrLn$listM'a''b''c'
abc
*Main>listm12::[Int]
[1,2]
*Main>sum$listm1 2
3.
*Main>listm1::[Int]
[1]
*Main>:t listM'a'True
:1:7:
无法将类型“Bool”与“Char”匹配
在'listM'的第一个参数中,即'a'
在表达式中:listM'a'True
*Main>:t listm2“foo”
:1:7:
没有(Num[Char]的实例)
源于字面上的“2”
可能的修复方法:为(Num[Char])添加实例声明
在'listM'的第一个参数中,即'2'
在表达式中:listm2“foo”
键入安全和理智默认值!这完美地回答了这个问题,同时也巧合地回答了这个问题