我正在https://rosettacode.org/wiki/Zebra_puzzle#LP-like_version研究代码并且有些困惑。
以下是该代码中发生的事情的最小示例。
import Control.Monad
import Data.List
values :: (Bounded a, Enum a) => [[a]]
values = permutations [minBound..maxBound]
data Nation = English | Swede | Dane
deriving (Bounded, Eq, Enum, Show)
data Color = Red | Blue | Green
deriving (Bounded, Eq, Enum, Show)
answers = do
nation <- values
begin nation English
color <- values
end color Red
return $ zip nation color
where
end xs x = guard $ last xs == x
begin xs x = guard $ head xs == x
main :: IO ()
main = do
forM_ answers $ (\answer -> -- for answer in answers:
do
mapM_ print answer
putStrLn "----" )
putStrLn "No more solutions!"
对我来说,神秘的是do块中发生的事情。
我从各种渠道了解到a <- b
运算符执行了一个操作b
并将其绑定到a
。但这里的行动到底是什么?
我认为它是values
,但如果我注释掉begin
和end
函数调用和定义,那么haskell就不知道如何处理values
了。我想这是因为他们定义中的相等测试是让haskell推断出类型的原因(我错了吗?)。
values
如何知道将permutations
应用于哪个有界类型?这部分看起来很神秘。 begin
和end
)我将如何做到这一点?答案 0 :(得分:0)
您可以将do
表示法翻译成列表理解符号:
answers = [ zip nation color
| nation <- values, head nation == English
, color <- values, last color == Red
]
我真的不喜欢这个head
和last
业务。