Haskell:如果x>;为矩阵值指定唯一字符;0

Haskell:如果x>;为矩阵值指定唯一字符;0,haskell,matrix,increment,Haskell,Matrix,Increment,因此,我的目标是让程序接收一个Int矩阵作为输入,程序将所有大于0的数字转换为一个唯一的顺序字符,而将0转换为一个“u”(没关系,只是序列中没有的任何字符) 例如 我所能做到的最好的是 [["_aa"],["aa_"],["__a"]] 使用: matrixGroupings xss = map (map (\x -> if x > 0 then 'a' else '_')) xss 据我所知,我遇到的问题是让程序记住它的最后一个值是什么,这样当值检查大于0时,它会选择行中的下一

因此,我的目标是让程序接收一个Int矩阵作为输入,程序将所有大于0的数字转换为一个唯一的顺序字符,而将0转换为一个“u”(没关系,只是序列中没有的任何字符)

例如

我所能做到的最好的是

[["_aa"],["aa_"],["__a"]]
使用:

matrixGroupings xss = map (map (\x -> if x > 0 then 'a' else '_')) xss
据我所知,我遇到的问题是让程序记住它的最后一个值是什么,这样当值检查大于0时,它会选择行中的下一个字符。但我一辈子都不知道该怎么做


如果有任何帮助,我们将不胜感激。

您的问题是一种古老艺术的实例:用一股水流标记各种结构 标签。它至少可以追溯到,我最喜欢的治疗方法是by

从这两个例子中可以看出,结构的方式可能有一些变化 贴标签于。但在目前的情况下,我想最直接的方法就是这样。在哈斯克尔 它会很短。让我们潜水吧

配方如下:
  • 为矩阵定义多态类型。它必须是这样的,一个数字矩阵和一个 字符矩阵都是合法成员
  • 提供可遍历的
    类的实例。在许多情况下,它可能是自动导出的
  • 挑一个你喜欢的单子。一个简单的选择是
    状态
    。(事实上,这是我唯一的选择 (我能想到。)
  • 在此单子中创建一个动作,该动作将数字转换为字符
  • 使用此操作遍历矩阵
让我们做饭吧!
  • 一种类型可以如此简单:

    newtype Matrix a = Matrix [[a]] deriving Show
    
    完全有可能内部列表的长度不相等-这种类型不相同 保护我们不被“破烂”的矩阵。这是拙劣的设计。但我要略读一下 这是暂时的。哈斯克尔提供了一个完美的选择。这种款式适合你穿 我们在这里的需要

    我们可以立即定义一个矩阵示例:

    example :: Matrix Int
    example = Matrix [[0,2,1],[2,2,0],[0,0,2]]
    
  • 定义可遍历的
    有多难?0硬

    {-# language DeriveTraversable #-}
    
    ...
    
    newtype Matrix a = Matrix [[a]] deriving (Show, Functor, Foldable, Traversable)
    
    普雷斯托

  • 我们从哪里得到标签?这是一个副作用。函数到达某个地方,需要一段时间 标签流,将头部和尾部放回额外尺寸的口袋中。A. 可以这样做的monad是
    状态

  • 它的工作原理如下:

    label :: Int -> State String Char
    label 0 = return '_'
    label x = do
        ls <- get
        case ls of
            [ ] -> error "No more labels!"
            (l: ls') -> do
                put ls'
                return l
    
就是这样。 祝你胃口好!


p.S.我夺走了你所有的荣誉,这是不公平的。为了让事情再次变得有趣,我向您挑战了一个练习:您能定义一个
可遍历的
实例以另一种顺序标记矩阵吗?先按列,然后按行?

非常感谢!虽然出于某种原因,我无法在代码中使用{-#extension#-}格式,但我不得不使用:set-XDeriveTraversable@netugi您需要将它放在
模块之前。。。where
行。谢谢。我只是想让你知道我确实试了一下你的练习,但我现在不想花太多时间在上面,因为这是几天后要交的一个大的大学作业。如果在那之后我有空的话,我会再试一次。我很感激这个挑战,它帮助我更好地理解代码的工作原理。
label :: Int -> State String Char
label 0 = return '_'
label x = do
    ls <- get
    case ls of
        [ ] -> error "No more labels!"
        (l: ls') -> do
            put ls'
            return l
matrixGroupings m = evalState (traverse label m) ['a'..'z']
λ matrixGroupings example
Matrix ["_ab","cd_","__e"]