Haskell:如果x>将唯一的char分配给矩阵值. 0 [英] Haskell: Assigning unique char to matrix values if x > 0

查看:115
本文介绍了Haskell:如果x>将唯一的char分配给矩阵值. 0的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我程序的目标是接收一个Int矩阵供输入,程序将所有大于0的数字转换为唯一的连续字符,而0则转换为'_'(没关系,只是任何字符)不在顺序中.)

So my goal for the program is for it to receive an Int matrix for input, and program converts all numbers > 0 to a unique sequential char, while 0's convert into a '_' (doesn't matter, just any character not in the sequence).

例如

main> matrixGroupings [[0,2,1],[2,2,0],[[0,0,2]]
[["_ab"],["cd_"],["__e"]]

我能达到的最好成绩是

[["_aa"],["aa_"],["__a"]]

使用:

matrixGroupings xss = map (map (\x -> if x > 0 then 'a' else '_')) xss

据我所知,我遇到的问题是让程序记住其最后一个值是什么,因此,当值检查> 0时,它将选择行中的下一个字符.尽管我一生都无法弄清楚该怎么做.

As far as I can tell, the issue I'm having is getting the program to remember what its last value was, so that when the value check is > 0, it picks the next char in line. I can't for the life of me figure out how to do this though.

任何帮助将不胜感激.

推荐答案

您的问题是一门古代艺术的实例:用流标记各种结构 标签.它至少可以追溯到 Chris Okasaki ,而我最喜欢的治疗方法是 Jeremy 长臂猿.

Your problem is an instance of an ancient art: labelling of various structures with a stream of labels. It dates back at least to Chris Okasaki, and my favourite treatment is by Jeremy Gibbons.

从这两个示例中可以看到,结构可能存在多种变化 贴上标签.但是在这种情况下,我想最直接的方法就是这样做.在哈斯克尔 这真的很短.让我们潜入.

As you can see from these two examples, there is some variety to the way a structure may be labelled. But in this present case, I suppose the most straightforward way will do. And in Haskell it would be really short. Let us dive in.

  • 为矩阵定义一个多态类型.它必须是一个数字矩阵和一个 字符矩阵都是合法的成员.
  • 提供Traversable类的实例.在许多情况下,它可能是自动得出的.
  • 按自己的喜好选择单子.一个简单的选择是State. (实际上,这是我唯一的选择 可以想到的.)
  • 在此monad中创建一个动作,该动作将一个数字带到一个字符上.
  • 使用此动作遍历矩阵.
  • Define a polymorphic type for your matrices. It must be such that a matrix of numbers and a matrix of characters are both rightful members.
  • Provide an instance of Traversable class. It may in many cases be derived automagically.
  • Pick a monad to your liking. One simple choice is State. (Actually, that is the only choice I can think of.)
  • Create an action in this monad that takes a number to a character.
  • Traverse a matrix with this action.
  • 类型可能像这样简单:

  • A type may be as simple as this:

newtype Matrix a = Matrix [[a]] deriving Show

内部列表完全有可能具有不相等的长度-这种类型不会 保护我们避免制作衣衫" 矩阵.这是糟糕的设计.但是我要浏览 现在. Haskell提供了无尽的深度来完善.此类型对于足够好 我们的需求在这里.

It is entirely possible that the inner lists will be of unequal length — this type does not protect us from making a "ragged" matrix. This is poor design. But I am going to skim over it for now. Haskell provides an endless depth for perfection. This type is good enough for our needs here.

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

We can immediately define an example of a matrix:

example :: Matrix Int
example = Matrix [[0,2,1],[2,2,0],[0,0,2]]

  • 定义Traversable有多难? 0硬.

  • How hard is it to define a Traversable? 0 hard.

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

    Presto.

    我们从哪里获得标签?这是一个副作用.函数到达某处,需要一个 标签流,将头部放回去,然后将尾巴放回超尺寸的口袋中.一种 可以执行此操作的monad是State.

    Where do we get labels from? It is a side effect. The function reaches somewhere, takes a stream of labels, takes the head, and puts the tail back in the extra-dimensional pocket. A monad that can do this is State.

    它的工作原理是这样的:

    It works like this:

    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
    

    我希望代码能自我解释.当函数创建" 一个单子值时,我们称其为 有效" 或给定单子中的动作" .例如,print是一个动作, 好吧,打印东西.这是一个效果. label也是一个动作,尽管不同 单子.比较并自己查看.

    I hope the code explains itself. When a function "creates" a monadic value, we call it "effectful", or an "action" in a given monad. For instance, print is an action that, well, prints stuff. Which is an effect. label is also an action, though in a different monad. Compare and see for youself.

    现在我们准备好准备解决方案了:

    Now we are ready to cook a solution:

    matrixGroupings m = evalState (traverse label m) ['a'..'z']
    

  • λ matrixGroupings example
    Matrix ["_ab","cd_","__e"]
    

    胃口好!

     

    Bon appetit!

     

    PS  我从你身上夺走了所有的荣耀,这是不公平的.为了使事情再次变得有趣,我向您挑战一个练习:您可以定义一个Traversable实例,以另一种顺序标记矩阵吗?先按列,然后按行?

    P.S.   I took all glory from you, it is unfair. To make things fun again, I challenge you for an exercise: can you define a Traversable instance that labels a matrix in another order — by columns first, then rows?

    这篇关于Haskell:如果x&gt;将唯一的char分配给矩阵值. 0的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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