简体   繁体   English

如何在 haskell 中返回同一 function 中的不同类型?

[英]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 ,则需要使用Res1Res2数据构造函数:

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 bsort 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM