从 haskell 中的列表中提取
Extracting from a list in haskell
我是 Haskell 的新手,并不完全理解 Maybe monad。
data Hmm = Hmm [Maybe Int]
deriving (Show, Eq)
yd = Hmm [Just 8, Just 5,Nothing,Just 2, Nothing, Just 2, Nothing,Nothing]
getVal = case yd of
[Just val] -> putStr val
[Nothing] -> putStr "."
我想通过将 Nothing 替换为一个点并将 Just n 替换为 n(全部在一行中)来提取我的列表。但是,这段代码给我一个错误。
Couldn't match expected type "Hmm" with actual type '[Maybe a0]'
In the pattern : [Nothing]
In a case alternative: [Nothing] -> putStr "."
In the expression:
case yd of
[Just val] -> putStr val
[Nothing] -> putStr "."
基本上我希望上面的列表采用“85.2.2..”格式
报错信息告诉你错误:
Couldn't match expected type "Hmm" with actual type '[Maybe a0]'
让我们通过使用 [Int]
而不是 [Maybe Int]
来简化,这样我们就可以将 monad 完全排除在外。让我们使用 0
代替 Nothing
和 x
代替 Just x
来重写您的测试用例
data Hmm = Hmm [Int]
deriving (Show, Eq)
yd = Hmm [8, 5, 0, 2, 0, 2, 0, 0]
getVal = case yd of
[0] -> putStr "."
[x] -> putStr $ show x
-- N.B. I had to reverse the order here since `[x]` will match before `[0]`.
-- This isn't an issue when you're still using Maybes, since Just x doesn't match Nothing
现在我们根本没有单子元素(getVal :: Hmm -> IO ()
除外,但是...)您仍然会遇到与以前相同的问题。 yd
构造为 Hmm
,但您在其上进行的唯一模式匹配是寻找 [a]
。此外,这两种模式都只查找单元素列表,因此即使 yd :: [Int]
.
它们也不会匹配
让我们在模式匹配中使用 Hmm
构造函数重写并正确递归以捕获整个列表。我们还将重写 getVal
到 return 和 String
,这样我们甚至不必弄乱 putStr :: String -> IO ()
[=53] 的 IO
monad =]s.
import Data.Char (intToDigit)
data Hmm = Hmm [Int]
deriving (Show, Eq)
yd = Hmm [8, 5, 0, 2, 0, 2, 0, 0]
getVal :: Hmm -> String
getVal (Hmm []) = []
getVal (Hmm (0:xs) = '.' : getVal (Hmm xs)
getVal (Hmm (x:xs) = intToDigit x : getVal (Hmm xs)
result :: String
result = getVal yd
注意我是如何在我的模式匹配中包含三个交替的。一个用于 Hmm []
-- 一个用 Hmm
类型包装的空列表,一个用于 Hmm (0:xs)
-- 一个由第一个值为零的 Hmm
包装的非空列表,一个用于 Hmm (x:xs)
—— 一个由 Hmm
包裹的非空列表,除第一个结果外,每个结果都是递归的。这将 return:
getVal yd =
getVal (Hmm (8:[5, 0, 2, 0, 2, 0, 0])) =
'8' : getVal (Hmm (5: [0, 2, 0, 2, 0, 0])) =
'8':'5' : getVal (Hmm (0: [2, 0, 2, 0, 0])) =
'8':'5':'.' : getVal (Hmm (2: [0, 2, 0, 0])) =
'8':'5':'.':'2' : getVal (Hmm (0: [2, 0, 0])) =
'8':'5':'.':'2':'.' : getVal (Hmm (2: [0, 0])) =
'8':'5':'.':'2':'.':'2' : getVal (Hmm (0: [0])) =
'8':'5':'.':'2':'.':'2':'.' : getVal (Hmm (0:[])) =
'8':'5':'.':'2':'.':'2':'.':'.': getVal (Hmm []) = -- base case!
'8':'5':'.':'2':'.':'2':'.':'.':[] = -- re-write as list
['8', '5', '.', '2', '.', '2', '.', '.'] -- re-write as String
"85.2.2.."
请注意,这只是:
toString :: Hmm -> String
toString (Hmm xs) = map f xs where
f 0 = '.'
f x = intToDigit x
要在此处使用 Maybe Int
并将此 return 用于 monad 世界,只需对您的代码应用相同的更改
import Data.Char (intToDigit)
data Hmm = Hmm [Maybe Int]
deriving (Show, Eq)
yd = Hmm [Just 8, Just 5, Nothing, Just 2, Nothing, Just 2, Nothing, Nothing]
getVal :: Hmm -> String
getVal (Hmm []) = []
getVal (Hmm (Nothing:xs)) = '.' : getVal (Hmm xs)
getVal (Hmm (Just x :xs)) = intToDigit x : getVal (Hmm xs)
-- or equivalently
getVal' :: Hmm -> String
getVal' (Hmm xs) = map f xs where
f Nothing = '.'
f (Just x) = intToDigit x
我是 Haskell 的新手,并不完全理解 Maybe monad。
data Hmm = Hmm [Maybe Int]
deriving (Show, Eq)
yd = Hmm [Just 8, Just 5,Nothing,Just 2, Nothing, Just 2, Nothing,Nothing]
getVal = case yd of
[Just val] -> putStr val
[Nothing] -> putStr "."
我想通过将 Nothing 替换为一个点并将 Just n 替换为 n(全部在一行中)来提取我的列表。但是,这段代码给我一个错误。
Couldn't match expected type "Hmm" with actual type '[Maybe a0]'
In the pattern : [Nothing]
In a case alternative: [Nothing] -> putStr "."
In the expression:
case yd of
[Just val] -> putStr val
[Nothing] -> putStr "."
基本上我希望上面的列表采用“85.2.2..”格式
报错信息告诉你错误:
Couldn't match expected type "Hmm" with actual type '[Maybe a0]'
让我们通过使用 [Int]
而不是 [Maybe Int]
来简化,这样我们就可以将 monad 完全排除在外。让我们使用 0
代替 Nothing
和 x
代替 Just x
data Hmm = Hmm [Int]
deriving (Show, Eq)
yd = Hmm [8, 5, 0, 2, 0, 2, 0, 0]
getVal = case yd of
[0] -> putStr "."
[x] -> putStr $ show x
-- N.B. I had to reverse the order here since `[x]` will match before `[0]`.
-- This isn't an issue when you're still using Maybes, since Just x doesn't match Nothing
现在我们根本没有单子元素(getVal :: Hmm -> IO ()
除外,但是...)您仍然会遇到与以前相同的问题。 yd
构造为 Hmm
,但您在其上进行的唯一模式匹配是寻找 [a]
。此外,这两种模式都只查找单元素列表,因此即使 yd :: [Int]
.
让我们在模式匹配中使用 Hmm
构造函数重写并正确递归以捕获整个列表。我们还将重写 getVal
到 return 和 String
,这样我们甚至不必弄乱 putStr :: String -> IO ()
[=53] 的 IO
monad =]s.
import Data.Char (intToDigit)
data Hmm = Hmm [Int]
deriving (Show, Eq)
yd = Hmm [8, 5, 0, 2, 0, 2, 0, 0]
getVal :: Hmm -> String
getVal (Hmm []) = []
getVal (Hmm (0:xs) = '.' : getVal (Hmm xs)
getVal (Hmm (x:xs) = intToDigit x : getVal (Hmm xs)
result :: String
result = getVal yd
注意我是如何在我的模式匹配中包含三个交替的。一个用于 Hmm []
-- 一个用 Hmm
类型包装的空列表,一个用于 Hmm (0:xs)
-- 一个由第一个值为零的 Hmm
包装的非空列表,一个用于 Hmm (x:xs)
—— 一个由 Hmm
包裹的非空列表,除第一个结果外,每个结果都是递归的。这将 return:
getVal yd =
getVal (Hmm (8:[5, 0, 2, 0, 2, 0, 0])) =
'8' : getVal (Hmm (5: [0, 2, 0, 2, 0, 0])) =
'8':'5' : getVal (Hmm (0: [2, 0, 2, 0, 0])) =
'8':'5':'.' : getVal (Hmm (2: [0, 2, 0, 0])) =
'8':'5':'.':'2' : getVal (Hmm (0: [2, 0, 0])) =
'8':'5':'.':'2':'.' : getVal (Hmm (2: [0, 0])) =
'8':'5':'.':'2':'.':'2' : getVal (Hmm (0: [0])) =
'8':'5':'.':'2':'.':'2':'.' : getVal (Hmm (0:[])) =
'8':'5':'.':'2':'.':'2':'.':'.': getVal (Hmm []) = -- base case!
'8':'5':'.':'2':'.':'2':'.':'.':[] = -- re-write as list
['8', '5', '.', '2', '.', '2', '.', '.'] -- re-write as String
"85.2.2.."
请注意,这只是:
toString :: Hmm -> String
toString (Hmm xs) = map f xs where
f 0 = '.'
f x = intToDigit x
要在此处使用 Maybe Int
并将此 return 用于 monad 世界,只需对您的代码应用相同的更改
import Data.Char (intToDigit)
data Hmm = Hmm [Maybe Int]
deriving (Show, Eq)
yd = Hmm [Just 8, Just 5, Nothing, Just 2, Nothing, Just 2, Nothing, Nothing]
getVal :: Hmm -> String
getVal (Hmm []) = []
getVal (Hmm (Nothing:xs)) = '.' : getVal (Hmm xs)
getVal (Hmm (Just x :xs)) = intToDigit x : getVal (Hmm xs)
-- or equivalently
getVal' :: Hmm -> String
getVal' (Hmm xs) = map f xs where
f Nothing = '.'
f (Just x) = intToDigit x