Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
List &引用;武当;在列表中_List_Haskell_Syntax_List Comprehension_Infinite - Fatal编程技术网

List &引用;武当;在列表中

List &引用;武当;在列表中,list,haskell,syntax,list-comprehension,infinite,List,Haskell,Syntax,List Comprehension,Infinite,我有如下几点: [bla z|n<-[0..], let z = foo n, z < 42] [bla z|n对此我没有一个好的答案,所以我只建议一个让您尽可能多地使用列表理解的乱码: map snd . takeWhile fst $ [(z < 42, bla z)|n<-[0..], let z = foo n] map snd.takeWhile fst$ [(zarbitral(F a)其中 任意=F任意 实例显示(a->b)其中 显示功能 道具单

我有如下几点:

[bla z|n<-[0..], let z = foo n, z < 42]

[bla z|n对此我没有一个好的答案,所以我只建议一个让您尽可能多地使用列表理解的乱码:

map snd . takeWhile fst $
    [(z < 42, bla z)|n<-[0..], let z = foo n]
map snd.takeWhile fst$

[(z<42,bla z)|n由于列表理解不允许这样做,我使用单子理解和定义自定义单子进行了一些黑客攻击。其结果是以下工作:

example :: [Int]
example = toList [1000 + n 
                 | n <- fromList [0..]
                 , _ <- nonStopGuard (n > 1)
                 , let z = 10*n
                 , _ <- stopGuard (z < 42) ]

-- Output: [1002,1003,1004]
上面的
Bool
是一个停止位,表明我们必须停止考虑进一步的选择

instance Applicative F where pure = return; (<*>) = ap
instance Monad F where
   return x = F [x] False
   F [] s      >>= _ = F [] s
   F (x:xs) sx >>= f = F (ys ++ zs) (sx || sy || sz)
      where 
      F ys sy = f x
      F zs sz = if sy then F [] False else F xs sx >>= f
一个普通的守卫从不发出停止的信号。它只提供一个或零个选择

stopGuard :: Bool -> F ()
stopGuard True  = F [()] False
stopGuard False = F [] True
相反,一个停车防护装置发出信号,一旦它变为错误,就立即停车

fromList :: [a] -> F a
fromList xs = F xs False

toList :: F a -> [a]
toList (F xs _) = xs
最后一条警告:我不能完全确定我的monad实例定义了一个实际的monad,即它是否满足monad定律


根据@icktoofay的建议,我编写了一些快速检查测试:

instance Arbitrary a => Arbitrary (F a) where
   arbitrary = F <$> arbitrary <*> arbitrary

instance Show (a -> b) where
   show _ = "function"

prop_monadRight :: F Int -> Bool
prop_monadRight m =
   (m >>= return) == m

prop_monadLeft :: Int -> (Int -> F Int) -> Bool
prop_monadLeft x f =
   (return x >>= f) == f x

prop_monadAssoc :: F Int -> (Int -> F Int) -> (Int -> F Int) -> Bool
prop_monadAssoc m f g =
   ((m >>= f) >>= g)
   ==
   (m >>= (\x -> f x >>= g))
instance arbitral a=>arbitral(F a)其中
任意=F任意
实例显示(a->b)其中
显示功能
道具单光::F Int->Bool
单道具m=
(m>>=返回)==m
prop_monadLeft::Int->(Int->F Int)->Bool
单德尔夫特x f号提案=
(返回x>>=f)==fx
莫纳达索克:F Int->(Int->F Int)->(Int->F Int)->布尔
莫纳达索克m f g提案=
((m>>=f)>>=g)
==
(m>>=(\x->fx>>=g))

运行100000个测试没有发现反例。因此,上面的
F
很可能是一个实际的单子。

这听起来是一个很好的点,停止使用列表理解,而是学习使用更高阶的列表函数,如中提供的函数

基本上,列表理解只是嵌套使用
concatMap::(a->[b])->[a]->[b]
的一种漂亮语法。因此,您最初的理解:

[bla z|n<-[0..], let z = foo n, z < 42]
一旦你把它写成这样,很容易看出这就是你想要的:

map bla (takeWhile (<42) (map foo [0..]))

map bla(takeWhile)(当然,对于列表理解来说,
takeWhile
没有语法糖分。但是,如果你使用
map
takeWhile
,它会变成
map bla$takeWhile(<42)$map foo[0..]
,我并不认为这是特别不雅的。你可以这样做
[bla z|z如果您为它实现
任意
,您可能可以使用快速检查来测试
F
是否为
Monad
。这完全是胡说八道。+1。@icktoofay谢谢,我刚刚尝试了您的建议。100000次测试后没有反例。
[bla z|n<-[0..], let z = foo n, z < 42]
let step n = let z = foo n
             in if z < 42 then [] else [bla z] 
in concatMap step [0..]
map bla (filter (<42) (map foo [0..]))
map bla (takeWhile (<42) (map foo [0..]))