我正在尝试附加适用于常规列表等嵌套列表的函数。我想使用Either String(嵌套a),以便它返回错误或附加列表。但它一直都在失败。我没有在任何地方做NestedList [NestedList a]。为什么说它预期[NestedList(NestedList a)]
module Main where
data NestedList a=Elem a | List[NestedList a] deriving Show
flatten ::NestedList a->[a]
flatten (Elem x)=[x]
flatten (List(x:xs))=flatten(x)++flatten(List xs)
--flatten NestedList (x:xs)=flatten(x)++flatten(xs)
flatten(List [])=[]
------------------
count::[a]->Int
count a=length (a)
-----------------
append::NestedList a->NestedList a->Either String (NestedList a)
append (_) (Elem a)=Left "Elements are not allowed"
append (Elem a) (_)=Left "Elements are not allowed"
append (List a) (List b)=Right (List (flatten(List a)++flatten(List b)))
-------------------
main=do
print(flatten (List[Elem 1, Elem 2,List[Elem 1, Elem 2 ]]))
print(count(flatten (List[Elem 1, Elem 2,List[Elem 1, Elem 2 ]])))
print(append (List[List[Elem 1, Elem 2 ]]) (List[Elem 1, Elem 2,List[Elem 1, Elem 2 ]] ))
给我这个错误
flatten_list.hs:18:52:
Couldn't match type `a' with `NestedList a'
`a' is a rigid type variable bound by
the type signature for
append :: NestedList a
-> NestedList a -> Either String (NestedList a)
at flatten_list.hs:15:9
Expected type: [NestedList (NestedList a)]
Actual type: [NestedList a]
In the first argument of `List', namely `a'
In the first argument of `flatten', namely `(List a)'
In the first argument of `(++)', namely `flatten (List a)'
flatten_list.hs:18:69:
Couldn't match type `a' with `NestedList a'
`a' is a rigid type variable bound by
the type signature for
append :: NestedList a
-> NestedList a -> Either String (NestedList a)
at flatten_list.hs:15:9
Expected type: [NestedList (NestedList a)]
Actual type: [NestedList a]
In the first argument of `List', namely `b'
In the first argument of `flatten', namely `(List b)'
In the second argument of `(++)', namely `flatten (List b)'
答案 0 :(得分:1)
import Data.Traversable
append :: NestedList a -> NestedList a -> Either String (NestedList a)
append (Elem x) (Elem y) = Right $ List [Elem x, Elem y]
append (Elem _) _ = Left ""
append _ (Elem _) = Left ""
append (List xs) (List ys) = fmap List $ sequenceA $ zipWith append xs ys
你在问题中写的追加似乎只是想要扁平化并连接两个列表,这是毫无意义的,因为你扔掉了所有的结构。如果这是所需的行为,那么只需使用常规列表:
append' :: NestedList a -> NestedList a -> Either String [a]
append' (Elem x) (Elem y) = Right $ [x,y]
append' (Elem _) _ = Left ""
append' _ (Elem _) = Left ""
append' a b = Right $ flatten a ++ flatten b
您还可以根据free monad:
定义数据类型import Control.Monad.Free
type NestedList = Free []
flatten :: NestedList a -> [a]
flatten = retract
append :: NestedList a -> NestedList a -> Either String (NestedList a)
append (Pure x) (Pure y) = Right $ Free [Pure x, Pure y]
append (Pure _) _ = Left ""
append _ (Pure _) = Left ""
append (Free xs) (Free ys) = fmap Free $ sequenceA $ zipWith append xs ys
这个定义与你给出的定义是同构的。