Haskell中的动态列表理解 [英] Dynamic List Comprehension in Haskell

查看:89
本文介绍了Haskell中的动态列表理解的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有一个列表理解返回一个序列列表,其中所选元素相互依赖(参见下面的示例)。有没有办法(方便地)基于更早的计算来编写元素的数量及其相关条件?例如,根据程序中的其他值返回类型[[a,b,c]]或[[a,b,c,d,e]]?另外,除了列表理解之外,还有其他更好的方法来制定相同的想法吗?



(我认为虽然繁琐且有限,但可以通过添加 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:

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆