Haskell中的动态列表理解 [英] Dynamic List Comprehension in Haskell
问题描述
(我认为虽然繁琐且有限,但可以通过添加 s a来编写更大的列表理解,参数和帮助函数,可以使一个或多个元素成为一个稍后可以轻松过滤的值,相关条件默认为True。)
s = [[a,b,c,d] | a< - list,someCondition a,
b< - list,b / = a,not(someCondition b),
otherCondition ab,
c< - list,c / = a, c / = b,not(someCondition c),
otherCondition bc,
d < - list,d / = a,d / = b,d / = c,
someCondition d,someCondition (last d),
otherCondition cd]
看起来你试图通过有限域的独特选择来解决一些逻辑难题。请教这些:
这对我们有帮助的方式是,当我们从中挑选时,并且下一个选择是从缩小的域中进行的,该域包含之前选择后留下的内容,因此链条自然形成。例如
p43 = sum [fromDigits [v0,v1,v2,v3,v4,v5,v6,v7,v8,v9 ]
| (dom5,v5)< -one_of [0,5] [0..9] - [0..9]是
,(dom6,v6)< - pick_any dom5 - 初始域
,(dom7,v7)< - pick_any dom6
,rem(100 * d5 + 10 * d6 + d7)11 == 0
....
- 从域中挑选一个elt的所有可能性
pick_any :: [a] - > [([a],a)]
pick_any [] = []
pick_any(x:xs)=(xs,x):[(x:dom,y)| (dom,y)< - pick_any xs]
- 从域中选择提供的elt之一的所有可能性
- (假定唯一域,即不重复)
one_of ::(等式a)=> [a] - > [a] - > [([a],a)]
one_of ns xs = [(ys,y)|让选择= pick_any xs,n <-ns,
(ys,y)< - 取1 $ filter((== n).snd)options]
您可以在答案中检查一些元素作为列表理解的一部分:
s = [answer | a< - ....,let answer = [....],length answer == 4]
或根据条件创建不同的答案,
s = [answer | a< - ....,let answer = if condition then [a,b,c] else [a]]
Suppose I have a list comprehension that returns a list of sequences, where the elements chosen depend on each other (see example below). Is there a way to (conveniently) program the number of elements and their associated conditions based on an earlier computation? For example, return type [[a,b,c]] or [[a,b,c,d,e]] depending on another value in the program? Also, are there other/better ways than a list comprehension to formulate the same idea?
(I thought possible, although cumbersome and limited, to write out a larger list comprehension to start with and trim it by adding to s a parameter and helper functions that could make one or more of the elements a value that could easily be filtered later, and the associated conditions True by default.)
s = [[a, b, c, d] | a <- list, someCondition a,
b <- list, b /= a, not (someCondition b),
otherCondition a b,
c <- list, c /= a, c /= b, not (someCondition c),
otherCondition b c,
d <- list, d /= a, d /= b, d /= c,
someCondition d, someCondition (last d),
otherCondition c d]
Looks like you're trying to solve some logic puzzle by unique selection from finite domain. Consult these:
- Euler 43 - is there a monad to help write this list comprehension?
- Splitting list into a list of possible tuples
The way this helps us is, we carry our domain around while we're making picks from it; and the next pick is made from the narrowed domain containing what's left after the previous pick, so a chain is naturally formed. E.g.
p43 = sum [ fromDigits [v0,v1,v2,v3,v4,v5,v6,v7,v8,v9]
| (dom5,v5) <- one_of [0,5] [0..9] -- [0..9] is the
, (dom6,v6) <- pick_any dom5 -- initial domain
, (dom7,v7) <- pick_any dom6
, rem (100*d5+10*d6+d7) 11 == 0
....
-- all possibilities of picking one elt from a domain
pick_any :: [a] -> [([a], a)]
pick_any [] = []
pick_any (x:xs) = (xs,x) : [ (x:dom,y) | (dom,y) <- pick_any xs]
-- all possibilities of picking one of provided elts from a domain
-- (assume unique domains, i.e. no repetitions)
one_of :: (Eq a) => [a] -> [a] -> [([a], a)]
one_of ns xs = [ (ys,y) | let choices = pick_any xs, n <- ns,
(ys,y) <- take 1 $ filter ((==n).snd) choices ]
You can trivially check a number of elements in your answer as a part of your list comprehension:
s = [answer | a <- .... , let answer=[....] , length answer==4 ]
or just create different answers based on a condition,
s = [answer | a <- .... , let answer=if condition then [a,b,c] else [a]]
这篇关于Haskell中的动态列表理解的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!