Haskell 中的数字字符映射与列表理解
Number-Character mapping in Haskell with list comprehension
我在 Haskell 中有一个简单的函数,它采用这样的元组列表:[(1,'a'),(2,'b')..(26,'z')]
和 returns 基于数字输入的字母值。所以理想情况下,
getCharByNum 3
> "c"
我正在通过使用列表理解来尝试此操作,并过滤掉不包含该数字的每个元组。
zippedChars = zip [ x | x <- [1..26]] [ x | x <- ['a'..'z']]
getCharByNum :: (Integral a) => a -> [Char]
getCharByNum num = [ head vector | vector <- zippedChars, num == last vector ]
我认为这是有道理的...getCharByNum 是一个接受整数的函数,returns 一个(短)字符列表。但是 GHCI 抛出这个错误:
Couldn't match expected type `[a]'
with actual type `(Integer, Char)'
In the first argument of `last', namely `vector'
In the second argument of `(==)', namely `last vector'
In the expression: num == last vector
如何正确构造允许此函数运行的类型签名? (我知道这可以通过索引轻松完成,或者使用 Data.Char.ord 更容易完成,但我试图更好地理解列表理解)
编辑:我稍微清理了一下代码:
zippedChars = zip [1..26] ['a'..'z']
getCharByNum :: Integral -> [Char]
getCharByNum num = [ c | (n,c) <- zippedChars, num == n ]
但我仍然收到此错误:
folds.hs:50:18:
Expecting one more argument to `Integral'
In the type signature for `getCharByNum':
getCharByNum :: (Integral) -> [Char]
Failed, modules loaded: none.
这是一个接受一个整数和 returns 一个字符列表的函数,所以我不确定我遗漏了什么。
您的问题是您正在使用 head
和 last
,它们仅适用于列表,而您的 vector
是一个元组。您需要改用 fst
和 snd
。或者更好的是,您可以使用模式匹配:
getCharByNum num = [ c | (n,c) <- zippedChars, num == n ]
顺便说一句,[ x | x <- [1..26]]
与 [1..26]
相同,字符列表也类似。
Integral 是一个类型类。积分不是一种类型。 a 是 Integral 的一个实例,所以我们在签名的开头声明它。
zippedChars :: Integral a => [(a, Char)]
zippedChars = zip [1..26] ['a'..'z']
getCharByNum :: Integral a => a -> String
getCharByNum num = [ c | (n,c) <- zippedChars, num == n ]
>>> getCharByNum 3
'c'
一条建议:
>>> ['a'..'z'] !! 4
'c'
我在 Haskell 中有一个简单的函数,它采用这样的元组列表:[(1,'a'),(2,'b')..(26,'z')]
和 returns 基于数字输入的字母值。所以理想情况下,
getCharByNum 3
> "c"
我正在通过使用列表理解来尝试此操作,并过滤掉不包含该数字的每个元组。
zippedChars = zip [ x | x <- [1..26]] [ x | x <- ['a'..'z']]
getCharByNum :: (Integral a) => a -> [Char]
getCharByNum num = [ head vector | vector <- zippedChars, num == last vector ]
我认为这是有道理的...getCharByNum 是一个接受整数的函数,returns 一个(短)字符列表。但是 GHCI 抛出这个错误:
Couldn't match expected type `[a]'
with actual type `(Integer, Char)'
In the first argument of `last', namely `vector'
In the second argument of `(==)', namely `last vector'
In the expression: num == last vector
如何正确构造允许此函数运行的类型签名? (我知道这可以通过索引轻松完成,或者使用 Data.Char.ord 更容易完成,但我试图更好地理解列表理解)
编辑:我稍微清理了一下代码:
zippedChars = zip [1..26] ['a'..'z']
getCharByNum :: Integral -> [Char]
getCharByNum num = [ c | (n,c) <- zippedChars, num == n ]
但我仍然收到此错误:
folds.hs:50:18:
Expecting one more argument to `Integral'
In the type signature for `getCharByNum':
getCharByNum :: (Integral) -> [Char]
Failed, modules loaded: none.
这是一个接受一个整数和 returns 一个字符列表的函数,所以我不确定我遗漏了什么。
您的问题是您正在使用 head
和 last
,它们仅适用于列表,而您的 vector
是一个元组。您需要改用 fst
和 snd
。或者更好的是,您可以使用模式匹配:
getCharByNum num = [ c | (n,c) <- zippedChars, num == n ]
顺便说一句,[ x | x <- [1..26]]
与 [1..26]
相同,字符列表也类似。
Integral 是一个类型类。积分不是一种类型。 a 是 Integral 的一个实例,所以我们在签名的开头声明它。
zippedChars :: Integral a => [(a, Char)]
zippedChars = zip [1..26] ['a'..'z']
getCharByNum :: Integral a => a -> String
getCharByNum num = [ c | (n,c) <- zippedChars, num == n ]
>>> getCharByNum 3
'c'
一条建议:
>>> ['a'..'z'] !! 4
'c'