我正在尝试编写一个函数,该函数生成一个列表列表,然后将一个函数应用于每个列表并将结果组合到一个大列表中。但是,我遇到了一个错误,如果有人能指出我正确的方向,我将不胜感激。
目前的代码如下所示:
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) 生成一个列表列表。那么为什么当我迭代时我只得到一个约束呢?
好吧,让我们逐步完成并添加有关类型的注释
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)