在包含单个元素和列表的列表上进行 Fmap
Fmap over a list containing single elements and lists
我有这样的数据结构
data ShoppingList a
= Empty
| Item a
| Listofitems [ShoppingList a]
deriving (Show)
我正在尝试为此编写 fmap
instance Functor ShoppingList where
fmap f Empty = Empty
fmap f (Item i) = Item (f i)
fmap f (Listofitems [Empty]) = Empty
fmap f (Listofitems ((Item a):Listofitems [as])) = Listofitems $ (fmap f (Item a)) (fmap f Listofitems [as])
这是我到目前为止写的,但它没有编译,你能帮我理解这里的问题是什么,解释会很棒。
我遇到的两个错误
src\Ml.hs:19:33: error:
* Couldn't match expected type `[ShoppingList a]'
with actual type `ShoppingList a0'
* In the pattern: Listofitems [as]
In the pattern: (Item a) : Listofitems [as]
In the pattern: Listofitems ((Item a) : Listofitems [as])
* Relevant bindings include
a :: a (bound at src\Ml.hs:19:30)
f :: a -> b (bound at src\Ml.hs:19:8)
fmap :: (a -> b) -> ShoppingList a -> ShoppingList b
(bound at src\Ml.hs:16:3)
|
19 | fmap f (Listofitems ((Item a):Listofitems [as])) = Listofitems $ (fmap f (Item a)) (fmap f Listofitems [as])
| ^^^^^^^^^^^^^^^^
src\Ml.hs:19:68: error:
* Couldn't match expected type `b -> [ShoppingList b]'
with actual type `ShoppingList b'
* The function `fmap' is applied to three arguments,
but its type `(a -> b) -> ShoppingList a -> ShoppingList b'
has only two
In the second argument of `($)', namely
`(fmap f (Item a)) (fmap f Listofitems [as])'
In the expression:
Listofitems $ (fmap f (Item a)) (fmap f Listofitems [as])
* Relevant bindings include
f :: a -> b (bound at src\Ml.hs:19:8)
fmap :: (a -> b) -> ShoppingList a -> ShoppingList b
(bound at src\Ml.hs:16:3)
|
19 | fmap f (Listofitems ((Item a):Listofitems [as])) = Listofitems $ (fmap f (Item a)) (fmap f Listofitems [as])
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
基本上如果我有一个列表 = [ Item Apple ,Empty , [Item Banana ,Empty ] ]
我想要 fmap (++ M )list 到 return [Item AppleM .Empty .[Item BananaM ,Empty]]
数据类型注意事项
首先,您的数据类型过于复杂。项目列表确实应该是一个列表,所以你应该定义 data ShoppingList' a = ShoppingList' [a]
因为你无论如何都在使用列表。无需嵌套购物清单。
你的问题的解决方案
但是,如果您需要那样,这就是一个解决方案。注意我假设您不需要 ShoppingLists 列表,因为您的数据定义中已经有一个列表。所以你可以调用
--fmap :: (a -> b) -> ShoppingList a -> ShoppingList b
fmap _ Empty = Empty
fmap f (Item i) = Item (f i)
fmap f (Listofitems ls) = Listofitems $ map (fmap f) ls
>>fmap (++ "M") $ Listofitems [Item "Apple", Empty, Listofitems [Item "Banana", Empty]]
Listofitems [Item "AppleM",Empty,Listofitems [Item "BananaM",Empty]]
注:
- 您的字符串需要引号,
- 您需要在 Listofitems 上调用它
另请记住,如果您需要性能,字符串追加操作对于长字符串效率不高
我有这样的数据结构
data ShoppingList a
= Empty
| Item a
| Listofitems [ShoppingList a]
deriving (Show)
我正在尝试为此编写 fmap
instance Functor ShoppingList where
fmap f Empty = Empty
fmap f (Item i) = Item (f i)
fmap f (Listofitems [Empty]) = Empty
fmap f (Listofitems ((Item a):Listofitems [as])) = Listofitems $ (fmap f (Item a)) (fmap f Listofitems [as])
这是我到目前为止写的,但它没有编译,你能帮我理解这里的问题是什么,解释会很棒。 我遇到的两个错误
src\Ml.hs:19:33: error:
* Couldn't match expected type `[ShoppingList a]'
with actual type `ShoppingList a0'
* In the pattern: Listofitems [as]
In the pattern: (Item a) : Listofitems [as]
In the pattern: Listofitems ((Item a) : Listofitems [as])
* Relevant bindings include
a :: a (bound at src\Ml.hs:19:30)
f :: a -> b (bound at src\Ml.hs:19:8)
fmap :: (a -> b) -> ShoppingList a -> ShoppingList b
(bound at src\Ml.hs:16:3)
|
19 | fmap f (Listofitems ((Item a):Listofitems [as])) = Listofitems $ (fmap f (Item a)) (fmap f Listofitems [as])
| ^^^^^^^^^^^^^^^^
src\Ml.hs:19:68: error:
* Couldn't match expected type `b -> [ShoppingList b]'
with actual type `ShoppingList b'
* The function `fmap' is applied to three arguments,
but its type `(a -> b) -> ShoppingList a -> ShoppingList b'
has only two
In the second argument of `($)', namely
`(fmap f (Item a)) (fmap f Listofitems [as])'
In the expression:
Listofitems $ (fmap f (Item a)) (fmap f Listofitems [as])
* Relevant bindings include
f :: a -> b (bound at src\Ml.hs:19:8)
fmap :: (a -> b) -> ShoppingList a -> ShoppingList b
(bound at src\Ml.hs:16:3)
|
19 | fmap f (Listofitems ((Item a):Listofitems [as])) = Listofitems $ (fmap f (Item a)) (fmap f Listofitems [as])
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
基本上如果我有一个列表 = [ Item Apple ,Empty , [Item Banana ,Empty ] ] 我想要 fmap (++ M )list 到 return [Item AppleM .Empty .[Item BananaM ,Empty]]
数据类型注意事项
首先,您的数据类型过于复杂。项目列表确实应该是一个列表,所以你应该定义 data ShoppingList' a = ShoppingList' [a]
因为你无论如何都在使用列表。无需嵌套购物清单。
你的问题的解决方案
但是,如果您需要那样,这就是一个解决方案。注意我假设您不需要 ShoppingLists 列表,因为您的数据定义中已经有一个列表。所以你可以调用
--fmap :: (a -> b) -> ShoppingList a -> ShoppingList b
fmap _ Empty = Empty
fmap f (Item i) = Item (f i)
fmap f (Listofitems ls) = Listofitems $ map (fmap f) ls
>>fmap (++ "M") $ Listofitems [Item "Apple", Empty, Listofitems [Item "Banana", Empty]]
Listofitems [Item "AppleM",Empty,Listofitems [Item "BananaM",Empty]]
注:
- 您的字符串需要引号,
- 您需要在 Listofitems 上调用它
另请记住,如果您需要性能,字符串追加操作对于长字符串效率不高