如何在Haskell中实现迭代列表中所有值的for循环?

时间:2015-11-23 02:14:26

标签: python loops haskell for-loop

我是Haskell的新手以及函数式编程。我一直在寻找一种迭代列表中所有值的方法,但是找不到任何值。

以下是我想要实现的Python代码:

    matrix = [[2, 0, 1],[0, 1, 2],[1, 2, 0]]

    def is_associative(G):
        n = len(G)          
        return all(G[(G[x][y])][z] == G[x][(G[y][z])] for x in range(n) 
                   for y in range(n) for z in range(n))

    # is_associative(matrix) returns true

    def find_identity(G):
        n = len(G)
        for y in range(n):
            if all(G[x][y] == G[y][x] == x for x in range(n)):
                return y

    # find_identity(matrix) returns 1

以下是我目前在Haskell中所拥有的内容:

    isAssociative :: [[Int]] -> Bool
    isAssociative [[]] = False
    isAssociative test = do 
        let x = 0
        let y = 1
        let z = 2
        getValue test (getValue test x y) z == getValue test x (getValue test y z)

    getValue :: [[Int]] -> Int -> Int -> Int
    getValue list a b = list !! a !! b

    findIdentity :: [[Int]] -> Int
    findIdentity test = 
        if all isTrue [ (g x y == g y x) && (g y x == x ) | x <- [0..n-1], y <- [0..n-1]]
            then 1 -- how to return y?
            else 0 -- how to return nothing?
        where n = length test
              g = getValue test

我已经能够修复我的关联功能,但我仍然想要获得与Python函数一样的完全相同的功能。

编辑(部分解决 - 需要身份帮助)

    isAssociative :: [[Int]] -> Bool
    isAssociative [[]] = False
    isAssociative test = 
        all id [ g (g x y) z == g x (g y z) | x <- [0..n-1], y <- [0..n-1], z <- [0..n-1]]
        where n = length test
              g = getValue test

    getValue :: [[Int]] -> Int -> Int -> Int
    getValue list a b = list !! a !! b

1 个答案:

答案 0 :(得分:0)

以下是findIdentity部分:

findIdentity :: [[Int]] -> Maybe Int
findIdentity ls = find 0 ls $ transpose ls where
  n = length ls - 1
  find _ [] [] = Nothing
  find y xs ys = if map head xs == map head ys && map head xs == [0..n]
                 then Just y
                 else if n == y
                      then Nothing
                      else find (y+1) (map tail xs) (map tail ys)


transpose :: [[b]] -> [[b]]
transpose [] = []
transpose ls | (length $ head ls) == 1 = [map head ls]
             | otherwise = map head ls:(transpose $ map tail ls)