toe*_*itz 5 haskell functor traversable
我正在尝试使用 Data.Traversable 在 haskell 中遍历数据结构的所有成员,该数据记录在以下网址中:
http://hackage.haskell.org/package/base-4.6.0.1/docs/Data-Traversable.html http://www.haskell.org/haskellwiki/Foldable_and_Traversable
到目前为止,我已经提出了以下代码,据我所知,它缺少 Tr.Traversable 实例化的正确实现。
import qualified Data.Traversable as Tr
import qualified Data.Foldable as Fl
import Control.Monad
import Control.Applicative
data Test = Test { desc :: String
, value :: Int
}
data Data t = Data { foo :: t
, bar :: t
}
exampleData = Data { foo = Test "Foo" 1
, bar = Test "Bar" 2
}
instance Show Test where
show f = (desc f) ++ ": " ++ (show $ value f)
instance (Show a) => Show (Data a) where
show f = show (foo f)
instance Functor Data where
fmap = Tr.fmapDefault
instance Fl.Foldable Data where
foldMap = Tr.foldMapDefault
instance Tr.Traversable Data where
traverse f = Data f -- Try to show a Test entry inside the Data structure
--
-- traverse :: Applicative f => (a -> f b) -> t a -> f (t b)
--
main = do
putStrLn $ show exampleData
Tr.traverse (putStrLn show) exampleData
Run Code Online (Sandbox Code Playgroud)
我正在尝试打印 exampleData 中的所有项目,逐个成员并使用 show。我是否在正确的轨道上,应该如何实现可遍历的实例化?
我只会使用语言扩展来为我派生:
{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE DeriveTraversable #-}
{-# LANGUAGE DeriveFoldable #-}
import qualified Data.Traversable as Tr
import qualified Data.Foldable as Fl
import Control.Monad
import Control.Applicative
data Test = Test { desc :: String
, value :: Int }
data Data t = Data { foo :: t
, bar :: t } deriving (Functor, Tr.Traversable, Fl.Foldable)
exampleData = Data { foo = Test "Foo" 1
, bar = Test "Bar" 2
}
instance Show Test where
show f = (desc f) ++ ": " ++ (show $ value f)
instance (Show a) => Show (Data a) where
show f = show (foo f)
main = do
putStrLn $ show exampleData
Tr.traverse (putStrLn . show) exampleData
Run Code Online (Sandbox Code Playgroud)
> runhaskell test_traversable.hs
Foo: 1
Foo: 1
Bar: 2
()
Run Code Online (Sandbox Code Playgroud)
如果你想知道编译器如何自动实现它,你可以用-ddump-deriv标志编译它(稍微清理一下):
instance Functor Data where
fmap f (Data foo' bar') = Data (f foo') (f bar')
instance Tr.Traversable Data where
tr.traverse f (Data foo' bar') = Data <$> (f foo') <*> (f bar')
instance Fl.Foldable Data where
Fl.foldr f z (Data foo' bar') = f foo' (f bar' z)
Run Code Online (Sandbox Code Playgroud)