在 Haskell 中结合 double for 循环的结果

Lan*_*ana 0 haskell

我正在尝试编写一个函数,该函数生成一个列表列表,然后将一个函数应用于每个列表并将结果组合到一个大列表中。但是,我遇到了一个错误,如果有人能指出我正确的方向,我将不胜感激。

目前的代码如下所示:

solve_all :: [Constraint] -> Sol -> Sol -> CType -> [(Maybe Typing)]
solve_all c lam_env app_env t2= do 
  lst <- (simMatch c)
  forM lst $ \d -> do
    return $ case pleaseUnify d of  --ERROR HERE
      Right u -> Just substituteTyping u (lam_env .+. app_env, t2)
      Left _ -> Nothing
Run Code Online (Sandbox Code Playgroud)

在哪里:

simMatch :: [Constraint] -> [[Constraint]]

pleaseUnify :: [Constraint] -> Either String Unifcation

substituteTyping :: Unifcation -> Typing -> Typing

错误指向调用pleaseUnify d说我只传递了一个约束而不是一个列表

   • Couldn't match expected type ‘[Constraint]’
                  with actual type ‘Constraint’
Run Code Online (Sandbox Code Playgroud)

但是我遵循了在这个问题中使用 forM 的答案,在 haskell 中迭代了一个列表

我正在从 (simMatch c) 生成一个列表列表。那么为什么当我迭代时我只得到一个约束呢?

Tho*_*son 5

好吧,让我们逐步完成并添加有关类型的注释

solve_all :: [Constraint] -> Sol -> Sol -> CType -> [(Maybe Typing)]
solve_all c lam_env app_env t2 = do
Run Code Online (Sandbox Code Playgroud)

此时我们在列表 monad 中(返回值为[(Maybe Typing)])。

lst <- (simMatch c :: [[Constraint]])
Run Code Online (Sandbox Code Playgroud)

我们将一个变量绑定lst到列表 monad 中的 simMatch,所以lst :: [Constraint].

forM lst $ \d -> do
Run Code Online (Sandbox Code Playgroud)

对于lstnamed d... so 的每个元素d :: Constraint。

return $ case pleaseUnify d of  --ERROR HERE
Run Code Online (Sandbox Code Playgroud)

我们知道pleaseUnify :: [Constraint] -> who_cares我们想要,d :: [Constraint]但在上面看到它必须是一个类型Constraint。

你真的想使用 list monad 并命名一个中间值lst吗?也许你打算:

forM (simMatch c) $ \d ->
 return $ case pleaseUnify d of
  Right u -> Just (substituteTyping u (lam_env .+. app_env, t2)) -- Notice a fix here too
  Left _ -> Nothing
Run Code Online (Sandbox Code Playgroud)