我想表达以下Haskell代码,仅使用函子代数(即 - 不依赖于任何特定的容器类型,例如List):
ys = zipWith (+) (head xs : repeat 0)
(tail xs ++ [y])
Run Code Online (Sandbox Code Playgroud)
在我看来,应该有一种方法来做到这一点,只依靠Foldable(或者,也许Traversable),但我看不到它.
我在想:
haskell书要我实现可遍历的实例
newtype Constant a b = Constant { getConstant :: a }
Run Code Online (Sandbox Code Playgroud)
包括所有必要的超类.下面的代码通过Quickcheck/Checkers,但行为有趣
import Test.QuickCheck
import Test.QuickCheck.Checkers
import Test.QuickCheck.Classes
newtype Constant a b = Constant { getConstant :: a }
instance Functor (Constant a) where
fmap f (Constant a) = Constant a
instance Foldable (Constant a) where
foldr f z (Constant x) = z
instance Traversable (Constant a) where
traverse f (Constant a) = pure $ Constant a
type TI = []
main = do
let trigger = …Run Code Online (Sandbox Code Playgroud) 考虑以下Haskell语句:
mapM print ["1", "2", "3"]
Run Code Online (Sandbox Code Playgroud)
实际上,这按顺序打印"1","2"和"3".
问:你怎么知道那mapM会先打印出"1",然后打印出"2",并最终打印出"3".有没有保证会这样做?或者它是如何在GHC深度实施的巧合?
问题1 -
在Scala文档中,我发现Traversable是一个带有抽象方法的特征foreach:
http://www.scala-lang.org/docu/files/collections-api/collections.html
那么,为什么我可以实例化Traversable类型的对象?
val t = Traversable(1,2,3)
t.foreach(println _) //where is Scala picking foreach a definition from?
Run Code Online (Sandbox Code Playgroud)
问题2 - Traversable与List或Array等其他类有何不同?它是否属于Seq,Set或Map类别(我认为其他集合继承自Traversable)
问题3 -我能为做完全相同Iterable,即使按文档,可迭代有一个抽象方法,特点iterator:
val v1 = Iterator(1,2,3)
v1.foreach( println _)
Run Code Online (Sandbox Code Playgroud)
我错过了什么?
我正在研究以下一小段代码:
import Control.Monad
import Data.Aeson
import qualified Data.HashMap.Strict as HashMap
import Data.Map (Map)
import qualified Data.Map as Map
import GHC.Generics
-- definitions of Whitelisted, WhitelistComment and their FromJSON instances
-- omitted for brevity
data Whitelist = Whitelist
{ whitelist :: Map Whitelisted WhitelistComment
} deriving (Eq, Ord, Show)
instance FromJSON Whitelist where
parseJSON (Object v) =
fmap (Whitelist . Map.fromList) . forM (HashMap.toList v) $ \(a, b) -> do
a' <- parseJSON (String a)
b' <- parseJSON b
return (a', …Run Code Online (Sandbox Code Playgroud) 我想创建以下特征:
trait IntSet[A] extends Traversable[A] { self: Product =>
def foreach[U](f: A => U): Unit
}
case class AProduct(a: List[Int], b: List[Int]) extends IntSet[Int] {
def foreach[U](f: Int => U): Unit = {
for(aa <- a; bb <- b) f(aa*bb)
}
}
AProduct(List(1, 5,6,7), List(2,3,4,5)).toString
Run Code Online (Sandbox Code Playgroud)
回报
(2, 3, 4, 5, 10, 15, 20, 25, 12, 18, 24, 30, 14, 21, 28, 35)
Run Code Online (Sandbox Code Playgroud)
但我不希望case类中的toString方法被遍历的一个覆盖!我该如何克服这个问题?
我希望最终输出为:
"AProduct(List(1, 5,6,7), List(2,3,4,5))"
Run Code Online (Sandbox Code Playgroud)
如果可能的话,我想在IntSet中做以下的事情:
override def toString = this.getClass().getName()+"("+self.productIterator.mkString(",")+")"
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中的一个序列?
假设:
我有一个简单的函数(实际上用于项目Euler的一些问题).它将数字列表转换为十进制数.
fromDigits :: [Int] -> Integer
fromDigits [x] = toInteger x
fromDigits (x:xs) = (toInteger x) * 10 ^ length xs + fromDigits xs
Run Code Online (Sandbox Code Playgroud)
我意识到这种类型[Int]并不理想.fromDigits应该能够采取其他输入,如序列,甚至可能foldables......
我的第一个想法是用"折叠状态"替换上面的代码.上述函数的正确(=最小)Haskell类别是什么?
(很抱歉有很长的上下文描述,但我找不到更简单的方法来解释我的问题)请考虑以下类型:
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) 我有一个玫瑰树结构,我想为其编写一个Traversable实例。因此,我从以下内容开始:
data Tree a = Tree a [Tree a] deriving (Show)
instance Functor Tree where
fmap f (Tree x subs) = Tree (f x) (fmap (fmap f) subs)
Run Code Online (Sandbox Code Playgroud)
我做了深度优先的变体:
newtype Depth a = Depth (Tree a) deriving (Show)
depth :: Tree a -> [a]
depth (Tree x subs) = x : concatMap depth subs
instance Functor Depth where
fmap f (Depth t) = Depth $ fmap f t
instance Foldable Depth where
foldMap f (Depth t) = mconcat …Run Code Online (Sandbox Code Playgroud)