繁体   English   中英

在 Haskell 中使用函子

[英]Using functor in haskell

我有一个以这种方式定义的 World 数据类型:

     data World = World
    { resolution :: (Int, Int)
    , direction :: Snake_direction
    , snake_scale :: Int
    , snake :: [(Int, Int)]
    , isStuck :: Bool
    , gen :: R.StdGen
    , food :: (Int, Int)
    , superFood :: (Int, Int)
    } deriving (Read, Show) 

我想使用一个在蛇列表上使用 fmap 的函子,它是世界数据类型的参数。 我正在为函子语法苦苦挣扎

instance Functor (World) where
    fmap f (World) = World {fmap f snake}

但编译器说

error: parse error on input ‘f’

另一种选择是不让World成为函子,因为您真正想要的是一种将函数映射到World值的一部分的方法。

snakeMap :: ((Int, Int) -> (Int, Int)) -> World -> World
snakeMap f w = w { snake = fmap f (snake w) }

如果我们检查Functor类型类,我们会看到:

class Functor (f :: * -> *) where
  fmap :: (a -> b) -> f a -> f b
  (<$) :: a -> f b -> f a
  {-# MINIMAL fmap #-}

所以f类型应该是* -> * ,一个带有类型参数的类型。 这不是这里的情况,所以我们不能将World声明为Functor的实例。 由于用户可以使用任何函数f :: a -> b将 a World a映射到World b ,但根本没有World a

如果你仍然想把它变成一个Functor ,我们可以先“升级” World类型,让它有一个类型参数:

data World a = World
    { resolution :: (Int, Int)
    , direction :: Snake_direction
    , snake_scale :: Int
    , snake :: [(a, a)]
    , isStuck :: Bool
    , gen :: R.StdGen
    , food :: (Int, Int)
    , superFood :: (Int, Int)
    } deriving (Read, Show)

那么我们可以定义一个fmap如下:

instance Functor World where
    fmap f w = w {snake = fmap (\(x,y) -> (f x, f y)) (snake w)}

或者如果你想直接在snakefmap ,而不是在snake坐标上:

data World a = World
    { resolution :: (Int, Int)
    , direction :: Snake_direction
    , snake_scale :: Int
    , snake :: a
    , isStuck :: Bool
    , gen :: R.StdGen
    , food :: (Int, Int)
    , superFood :: (Int, Int)
    } deriving (Read, Show)

那么我们可以定义一个fmap如下:

instance Functor World where
    fmap f w = w {snake = f (snake w)}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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