首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >从列表中选择一张特定的图片

从列表中选择一张特定的图片
EN

Stack Overflow用户
提问于 2018-12-08 14:22:09
回答 2查看 101关注 0票数 0

我的职能如下:

代码语言:javascript
运行
复制
blockToPicture :: Int -> [Picture] -> Picture
blockToPicture n [pic1,pic2,pic3] | n==0 = ...
                                  | n==1 = ...
                                  | otherwise = ...

如果n==0我想选择pic1,如果n==1我想选择pic2。否则,我想选择pic3。问题是当其中一张图片没有加载时,它就不会出现在列表中。而不是[pic1,pic2,pic3],我有一些类似于[Pic1,Pic3]的东西。当函数为supposed以选择不在列表中的图片时,我希望它可以编写"X"。为此,我将使用函数text "X"代替。问题是,我不知道如何让它编写"X",而不是选择错误的图片。

编辑:我创建了以下函数,但出于某种原因,我在图片中得到了错误“变量不在范围内”。

代码语言:javascript
运行
复制
blocoParaPicture :: Int -> [Picture] -> Picture
blocoParaPicture b l | b==0 = if elem pic1 l then pic1 else text "X"
                     | b==1 = if elem pic2 l then pic2 else text "X"
                     | otherwise = if elem pic3 l then pic3 else text "X"
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-12-08 17:19:05

您不能就这样丢弃不加载的图片;如果尝试加载3张图片并以[some_pic, some_other_pic]结束,您如何知道哪个图片没有加载?您需要一个类型为[Maybe Picture]的列表,其中Just pic表示成功加载的图片,Nothing表示失败。那么您的函数看起来就像

代码语言:javascript
运行
复制
blockToPicture :: Int -> [Maybe Picture] -> Maybe Picture
blockToPicture _ []          = Nothing                  -- No pictures to choose from
blockToPicture 0 (Nothing:_) = Nothing                  -- Desired picture failed to load
blockToPicutre 0 (x:_)       = x                        -- Found desired picture!
blockToPicture n (_:xs)      = blockToPicture (n-1) xs  -- This isn't it; try the next one

采用豪尔赫·阿德里亚诺的建议使用lookup (这是一个很好的建议)

代码语言:javascript
运行
复制
import Control.Monad

blockToPicture :: Int -> [Maybe Picture] -> Maybe Picture
blockToPicture n pics = join (lookup n (zip [0..] pics))

由于lookup :: a -> [(a,b)] -> Maybe bb在这里是Maybe Picture,所以我们有这样一个场景:如果n太大,lookup返回Nothing;如果所需的图片无法加载,则返回Just Nothing;如果找到所需的图片,则返回Just (Just pic)。来自Control.MonadControl.Monad函数减少了lookup返回给我们想要的“常规”Maybe PictureMaybe (Maybe Picture)值。

票数 1
EN

Stack Overflow用户

发布于 2018-12-08 15:17:12

blocoParaPicture ::Int -> Picture -> Picture blocoParaPicture b l b==0 = if elem pic1 l,然后pic1 blocoParaPicture文本"X“pic1 b==1 = if elem pic2 l然后pic2 blocoParaPicture文本"X”\x= if elem pic3 l然后pic3 blocoParaPicture text "X“ 我得到错误的“变量不在范围”的图片。

表达式elem x xs检查给定的x是否在list xs中。在编写pic1时,代码中没有这样的变量,在任何地方都没有定义。在任何情况下,您都不想在列表中搜索特定的值,而是想知道给定的位置是否“存在”,也就是说,列表是否足够长。

此外,您不能只在函数中使用这种类型“写”。在Haskell中,输入和输出反映在类型上。这是一个纯函数,它接受一些参数并计算结果,没有副作用。

因此,您可以在这里返回一个Maybe Picture,它的值是Nothing还是Just pic,这取决于您是否可以返回图片。也可以使用Either String Picture,其中值的形式为Left stringRight pic。让我们选择后一种选择。

代码语言:javascript
运行
复制
blocoParaPicture :: Int -> [Picture] -> Either String Picture

在实现方面,我们可能会偏离主题来讨论错误管理(因为问题是访问某个位置可能会失败)。但在这一点上,我认为最好避免这种迂回,所以让它保持(相对)简单。

直接递归(最简单)

最简单的最直接的方法是直接递归(如@chepner在下面的注释中所建议的)。

代码语言:javascript
运行
复制
blocoParaPicture :: Int -> [Picture] -> Either String Picture
blocoParaPicture _ []     = Left "X"
blocoParaPicture 0 (x:_)  = Right x
blocoParaPicture n (x:xs) = safe (n-1) xs

!! 确保继承

如果您确实想使用标准访问函数!!,一种方法是构造一个“安全”无限列表(但在一般情况下可能效率低下)。

代码语言:javascript
运行
复制
import Data.List 

blocoParaPicture :: Int -> [Picture] -> Either String Picture
blocoParaPicture n xs = zs !! n 
                        where zs = [Right x | x <- xs] ++ repeat (Left "X")

list zs是由两个列表组成的无限列表。第一个[Right x | x <- xs],它与原始列表一样,但是每个元素x都变成了Right x。然后,从那时起,所有元素都以Left "X"形式表示失败。一般而言,上述方法可能效率低下。如果您在列表中寻找一个大的n

代码语言:javascript
运行
复制
[Right 1, Right 2] ++ [Left "X", Left "X", ...

您正在执行许多不必要的步骤,因为您可以在第一个列表结束时停止。但对于小型n来说,效果很好。

使用lookup

还有一种类似于您尝试使用elem函数的可能性,就是在索引上使用lookup。通过设计,本功能安全可靠。

代码语言:javascript
运行
复制
lookup :: Eq a => a -> [(a, b)] -> Maybe b

按照这种方法,首先构造列表,

代码语言:javascript
运行
复制
[(0,x0), (1,x1), (2,x2) ...(k,xk)]

然后查找给定的n来返回关联的xn (或Nothing)。

代码语言:javascript
运行
复制
blocoParaPicture' :: Int -> [Picture] -> Maybe Picture
blocoParaPicture' n xs = lookup n (zip [1..] xs)

但是,当找不到时,这会返回Nothing。但是如果您愿意,可以通过Either通过maybe :: b -> (a -> b) -> Maybe a -> b进行转换。

代码语言:javascript
运行
复制
blocoParaPicture :: Int -> [Picture] -> Either String Picture
blocoParaPicture n xs = maybe (Left "X") Right (lookup n (zip [1..] xs))

当您只需要一个简单的访问函数时,这肯定有点复杂。但在事情不那么简单的情况下却很方便。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53683452

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档