我正在尝试编写自己的foldMap函数作为学习Haskell的例外
目前它看起来像这样
class Functor f => Foldable f where
fold :: Monoid m => f m -> m
foldMap :: Monoid m => (a -> m) -> f a -> m
foldMap g a = fold (<>) mempty (fmap g a)
Run Code Online (Sandbox Code Playgroud)
但是在编译时会出现以下错误
Could not deduce (Monoid ((f m -> m) -> fm -> m)) arising from use of 'fold'
from the context (Foldable f) bound by the class declaration for 'Foldable' at (file location)
or from (Monoid m) bound by …Run Code Online (Sandbox Code Playgroud) Maybe列表的Hackage文档可折叠为Maybe的类型类之一.它还列出了以下功能:
null :: Maybe a -> Bool
Run Code Online (Sandbox Code Playgroud)
它甚至链接到这个函数的实现(来自Foldable):
null :: t a -> Bool
null = foldr (\_ _ -> False) True
Run Code Online (Sandbox Code Playgroud)
......这似乎很合理.它也有效:如果我import qualified Data.Foldable,我可以使用foldrMaybe值.
但是,当我尝试调用nullMaybe时,Haskell认为我想使用为列表设计的null:
Prelude> :t null
null :: [a] -> Bool
Prelude> null Nothing
<interactive>:3:6:
Couldn't match expected type `[a0]' with actual type `Maybe a1'
In the first argument of `null', namely `Nothing'
In the expression: null Nothing
In an equation for `it': it = null Nothing
Run Code Online (Sandbox Code Playgroud)
我知道有isJust …
我有一个类似 Set 的数据结构,作为 Trie 实现,其定义如下:
import qualified Data.Map as M
import Data.Foldable (Foldable, foldr)
import Prelude hiding (foldr)
import Data.Maybe (fromMaybe)
data Trie a = Trie { endHere :: Bool
, getTrie :: M.Map a (Trie a)
} deriving (Eq)
Run Code Online (Sandbox Code Playgroud)
插入操作如下所示:
insert :: (Ord a, Foldable f) => f a -> Trie a -> Trie a
insert = foldr f (\(Trie _ m) -> Trie True m) where
f e a = overMap (M.alter (Just . a . fromMaybe (Trie …Run Code Online (Sandbox Code Playgroud) 对我来说,整数集似乎是一个可折叠的数据结构.为什么Data.IntSet不是一个实例Foldable?
我的目的是用上find一个IntSet.我该如何实现find Data.IntSet?
我想表达以下Haskell代码,仅使用函子代数(即 - 不依赖于任何特定的容器类型,例如List):
ys = zipWith (+) (head xs : repeat 0)
(tail xs ++ [y])
Run Code Online (Sandbox Code Playgroud)
在我看来,应该有一种方法来做到这一点,只依靠Foldable(或者,也许Traversable),但我看不到它.
我在想:
说我有一些简化的Lisp样式Expr类型,如下所示
data Expr = String String | Cons Expr Expr
deriving (Show)
Run Code Online (Sandbox Code Playgroud)
我可以将列表创建为Cons-cell的Cons-cell:
Cons (String "hello") (Cons (String "World") (String "!"))
Run Code Online (Sandbox Code Playgroud)
由此我想实现Foldable的Expr折叠超过这些缺点名单-但那是不可能的,因为Foldable需要一种类型的* -> *(即多态恰好与一个类型参数),我哪来Expr有样*。
这是为什么?在我看来,像这样折叠非多态类型是完全合理的,但是显然我缺少了一些东西。
我想实现折叠
data Constant a b = Constant a
Run Code Online (Sandbox Code Playgroud)
这是我直截了当的尝试:
instance Foldable (Constant a) where
foldr f b (Constant a) = f a b
Run Code Online (Sandbox Code Playgroud)
我想要理解的编译错误部分是:
Couldn't match expected type ‘a1’ with actual type ‘a’
‘a1’ is a rigid type variable bound by the type signature for
foldr :: (a1 -> b -> b) -> b -> Constant a a1 -> b
Run Code Online (Sandbox Code Playgroud)
你可以看到折叠函数a1从我无法访问的常量中获取"幻像类型"(?); 我只能访问a.
我该如何解决这个问题?请解释一下你的解决方案,因为我很困惑.
整个编译错误是:
try2/chap20/ex1.hs:9:30: Couldn't match expected type ‘a1’ with actual type ‘a’ …
‘a’ …Run Code Online (Sandbox Code Playgroud) 我正在尝试在不同的行上打印自相关结果的不同组成部分:
import Data.Vector as V
import Statistics.Autocorrelation
import Data.Typeable
sampleA = [1.0, 2.0, 3.0, 4.0, 1.0, 2.0, 3.0, 4]
main = do
let res = autocorrelation $ V.fromList sampleA
putStr "Type of result of autocorrelation test: "
print $ typeOf res
print res
-- Prelude.mapM_ print res -- not working;
Run Code Online (Sandbox Code Playgroud)
输出为:
Type of result of autocorrelation test: ((Vector Double),(Vector Double),(Vector Double))
([1.0,2.5e-2,-0.45,-0.325,0.5,0.125,-0.15],[1.0,-1.3255000000000001,-1.4039375473415425,-1.442999810318651,-1.5311377955236107,-1.5364636906417393,-1.544097864842309],[1.0,1.0755000000000001,1.1539375473415425,1.192999810318651,1.2811377955236107,1.2864636906417393,1.294097864842309])
Run Code Online (Sandbox Code Playgroud)
但是,如果取消注释最后一行,则会出现错误:
• No instance for (Foldable ((,,) (Vector Double) (Vector Double)))
arising from a use of …Run Code Online (Sandbox Code Playgroud) 在Haskell中,我们看到Haskell前奏中的Foldable和Traversable 登陆.
这些都对序列进行操作.
Prelude Data.Sequence> map (\n -> replicate n 'a') [1,3,5]
["a","aaa","aaaaa"]
Prelude Data.Sequence> fmap (\n -> replicate n 'a') (1 <| 3 <| 5 <| empty)
fromList ["a","aaa","aaaaa"]
Run Code Online (Sandbox Code Playgroud)
我的问题是Haskell的Foldable和Traversable只相当于Clojure中的一个序列?
假设:
(很抱歉有很长的上下文描述,但我找不到更简单的方法来解释我的问题)请考虑以下类型:
import Data.Array
data UnitDir = Xp | Xm | Yp | Ym | Zp | Zm
deriving (Show, Eq, Ord, Enum, Bounded, Ix)
type Neighborhood a = Array UnitDir (Tree a)
data Tree a = Empty | Leaf a | Internal a (Neighborhood a)
deriving (Eq, Show)
Run Code Online (Sandbox Code Playgroud)
显然,Tree可以定义Functor为如下实例:
instance Functor Tree where
fmap _ Empty = Empty
fmap f (Leaf x) = Leaf (f x)
fmap f (Internal x ts) = Internal (f x) $ …Run Code Online (Sandbox Code Playgroud)