[英]How to return different types in the same function in haskell?
I cannot understand why, although I have declared the data types, the function does not accept the different return.我不明白为什么,虽然我已经声明了数据类型,但 function 不接受不同的返回。 I also tried to create a "Result" type but it was not enough to solve the problem.我也尝试创建一个“结果”类型,但这还不足以解决问题。
Take a look at my code:看看我的代码:
type Set a = [a]
type Bag a = [(a, Int)]
type Seq a = [a]
data ComposedType a = Set a | Bag [a] | Seq a deriving(Eq, Show)
data ComposedResult a = Res1 [a] | Res2 [(a, Int)]
-- This function get a list [a] and returns a list of tuples [(a, Int)]
occrs :: (Ord a) => [a] -> [(a, Int)]
occrs [] = []
occrs xs = toList (fromListWith (+) [(x, 1) | x <- xs])
--getElements :: ComposedType a -> ComposedResult a
getElements (Set a) = (Set (nub a))
getElements (Seq a) = (Seq (sort a))
getElements (Bag a) = (Bag (occrs a))
The error:错误:
- Couldn't match type ([a], Int) with '[a]' Expected type: ComposedType [a] Actual type: ComposedType ([a], Int)无法将类型 ([a], Int) 与“[a]”匹配 预期类型:ComposedType [a] 实际类型:ComposedType ([a], Int)
- In the expression: (Bag (occrs a)) In an equation for 'getElements': getElements (Bag a) = (Bag (occrs a))在表达式中:(Bag (occrs a)) 在“getElements”的等式中:getElements (Bag a) = (Bag (occrs a))
The reason this does not work is because Set (num a)
for example has type ComposedType [a]
, whereas for the Bag (occrs)
, it will require ComposedTYpe (a, Int)
, since the Bag
uses, in contrast to the other data constructors a list of a
s: [a]
.这不起作用的原因是因为Set (num a)
例如具有类型ComposedType [a]
,而对于Bag (occrs)
,它将需要ComposedTYpe (a, Int)
,因为Bag
使用,与其他数据构造函数列表a
s: [a]
。
If you make use of a ComposedResult
, then you will need to use the Res1
and Res2
data constructors:如果使用ComposedResult
,则需要使用Res1
和Res2
数据构造函数:
getElements :: (Eq a, Ord a) => ComposedType [a] -> ComposedResult a
getElements (Set b) = Res1 (nub b)
getElements (Seq b) = Res1 (sort b)
getElements (Bag b) = Res2 (occrs b)
but this will still not work.但这仍然行不通。 Indeed Bag a
has a parameter b
, but that b
has as type [[a]]
, and although occrs
can work with a list of lists (since these are also an instance of Ord
if the element is an instance of ord
, this would mean that occrs b
has type [([a], Int)]
whereas the others ( nub b
and sort b
), have type [a]
, so that would again raise trouble.实际上Bag a
有一个参数b
,但是b
的类型是[[a]]
,尽管occrs
可以处理列表列表(因为如果元素是ord
的实例,这些也是Ord
的实例,这将意味着occrs b
具有类型[([a], Int)]
而其他( nub b
和sort b
)具有类型[a]
,因此会再次引发麻烦。
We can fix this by concatenating for example the elements of b
together:我们可以通过将b
的元素连接在一起来解决这个问题:
getElements :: (Eq a, Ord a) => ComposedType [a] -> ComposedResult a
getElements (Set b) = Res1 (nub b)
getElements (Seq b) = Res1 (sort b)
getElements (Bag bs) = Res2 (occrs (concat bs))
but likely you made a mistake by specifying [a]
as parameter for bag, you thus can fix the type and use:但是您可能通过将[a]
指定为 bag 的参数而犯了一个错误,因此您可以修复类型并使用:
data ComposedType a = Set a | Bag a | Seq a deriving (Eq, Show)
getElements :: (Eq a, Ord a) => ComposedType [a] -> ComposedResult a
getElements (Set b) = Res1 (nub b)
getElements (Seq b) = Res1 (sort b)
getElements (Bag b) = Res2 (occrs b)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.