data Rose a = MkRose a [Rose a]
deriving (Eq, Show)
-- Rose Int with two children
t1 = MkRose 3 [MkRose 9 [], MkRose 2 []]
data Field = X | O | B
deriving (Eq, Ord)
type Row = (Field, Field, Field)
type Board = (Row, Row, Row)
minimax :: Player -> Rose Board -> Rose Int
-- MkRose -1 [MkRose 1 [..], MkRose -1 [..], MkRose 1 [..] ]
minimax P1 (MkRose b bs)
= let bs' = minimax' (MkRose b bs)
-- :t bs' = MkRose (Board, Int)
-- [MkRose (Board,Int) [], MkRose (Board,Int) [] ]
in fmap snd bs'如果我有一个Rose (Board, Int),我希望能够将它转换成一个Rose Int。我从尝试一个Functor实例切换到仅在列表上使用fmap和snd,这在上面进行了更新,给了我这个错误:
error:
• No instance for (Functor Rose) arising from a use of ‘fmap’
• In the expression: fmap snd bs'
In the expression: let bs' = minimax' (MkRose b bs) in fmap snd bs'
In an equation for ‘minimax’:
minimax P1 (MkRose b bs)
= let bs' = minimax' (MkRose b bs) in fmap snd bs'
|
259 | in fmap snd bs'我怎么才能在Haskell完成这件事?或者,我可以只编写一个函数,如果这更容易的话。
发布于 2021-09-28 17:50:10
你不需要fmap
rmap :: (a -> b) -> Rose a -> Rose b
rmap f (MkRose a as) = MkRose (f a) (map (rmap f) as)但拥有
instance Functor Rose where fmap = rmap允许你做一些像(<$)这样的整洁的事情,你不需要一直记住map,rmap,vmap等等。
(而且,使用{-# LANGUAGE DeriveFunctor #-},您可以简单地编写data Rose a = MkRose a [a] deriving Functor,并且实例是为您计算的。)
发布于 2021-09-28 17:51:50
只需将Functor添加到deriving列表:
data Rose a = MkRose a [Rose a]
deriving (Eq, Show, Functor)您可能必须启用扩展DeriveFunctor。
那么您可以只使用fmap snd。
它将将Rose (a,b)转换为Rose b,用于任何类型的a和b。特别是对于(Board, Int),它将Rose (Board, Int)转换为Rose Int,只需去掉树中每个值位置中元组的第一个组件。
fmap :: Functor f => (a -> b) -> f a -> f b
fmap snd :: Functor f => f (a, b) -> f b
fmap @ Rose :: (a -> b) -> Rose a -> Rose b
fmap @ Rose @ (Board, Int) snd :: Rose (Board, Int) -> Rose Int这使用TypeApplications,但您不需要这样做,类型将根据您将提供的数据(即您将应用fmap snd的变量)自动选择。例如:
Prelude> t1 = MkRose (0,3) [MkRose (0,9) []]
Prelude> fmap snd t1
MkRose 3 [MkRose 9 []]
Prelude> 您在注释中所写的语法是无效的。
bs' = MkRose (Board, Int)
[MkRose (Board,Int) [], MkRose (Board,Int) [] ]如果你有这个作为代码,逐字。
你不能这么做。Board是一个类型的名称。Int是一个类型的名称。但是变量bs'应该引用一段数据。如果该数据为Rose (Bord, Int)类型,则意味着在类型变量a出现的每个地方,在数据类型定义中,
data Rose a = MkRose a [Rose a]
-- ^ ^应该出现一段(Board, Int)类型的数据--而不仅仅是输入名称。这是一个包含两个实际值的元组,一个是Board类型,另一个是Int类型。例如,使用Rose (String, Int)
t2 :: Rose (String, Int)
t2 = MkRose ("a", 1) [MkRose ("b", 2) [], MkRose ("c", 3) []]
fmap snd t2
=> MkRose 1 [MkRose 2 [], MkRose 3 []]https://stackoverflow.com/questions/69365893
复制相似问题