递归将3元组转换为char-Haskell

时间:2018-10-14 00:18:33

标签: haskell functional-programming

鉴于此功能,我想知道如何解决这个问题

#arr1 = 
#if (n%2==0):
#print (int (n/2))
import math
for i in range(int(n/2)):
    temp1 = (int_list[i])
    temp2 = x%10

    print (temp1)
    print (temp2)

    if temp1==temp2:
        x = floor(x/10)
        continue

    else:
        return False

return True

我有以下辅助功能,不确定是否需要

convertChar' :: [[(Int, Int, Int)]] -> [[Char]] 

toList :: [[(Int, Int, Int)]] -> [(Int, Int, Int)] toList [(x)] = (x) convertList :: [(Int, Int, Int)] -> [[(Int, Int, Int)]] convertList x = [x] 将是(Int, Int, Int)

  • 如果元组为(1,1,1),它将返回█字符。
  • 如果元组为(0,0,0),它将返回“”

我想知道解决这个问题的聪明方法是什么。 我是否必须将原始输入从[[()]]转换为[()] 应用这些函数,然后转换回[[()]],然后再次递归调用converChar函数?

1 个答案:

答案 0 :(得分:2)

我能想到的最好的答案是,您应该更改程序,以便您的类型代表您想要的。具体来说,当我查看您的代码时,似乎您已经拥有(或至少您认为/您没有,但是编写了错误的程序):

  1. 每个[[(Int,Int,Int)]]都是[xs]形式的列表
  2. 每个(Int,Int,Int)(0,0,0)(1,1,1)

首先,我将按照您的说明写下解决方案。其次,我将向您展示如何构造代表世界状态的类型(不允许您代表非法状态)。

renderThing (0,0,0) = ' '
renderThing (1,1,1) = '█'
renderState = map (map renderThing)

让我们对此进行简要描述。前两行定义了一个局部函数来执行您的int-triple-to-char函数,如上级中所述。

第三行定义所需的功能。让我们从左到右阅读它:

  1. renderState(类型为[[(Int,Int,Int)]] -> [[Char]]
  2. map renderThing :: [(Int,Int,Int)] -> [Char]应用于作为输入传递的列表的每个元素
    1. 要执行该功能,请将renderThing应用于内部列表的每个元素(我假设这是一行)

不幸的是,如果您违反了任何(Int,Int,Int)(0,0,0)(1,1,1)的隐式不变式,则程序将崩溃。更好的类型可以是(Bool,Bool,Bool),因为每个元素只能具有两个值之一。您可以执行的另一种方法是:

data Thing = White | Black

有两种方法可以将其放入程序中。要么在整个过程中都使用良好的类型,以便编译器可以确保您永远不会陷入意外状态,要么可以使用具有错误的转换函数:

renderableBoard :: [[(Int,Int,Int)]] -> Either String [[Thing]]
renderableBoard = mapM (mapM convertOne) where
  convertOne (0,0,0) = White
  convertOne (1,1,1) = Black
  convertOne x = "cannot concert to thing: " ++ show x