haskell - 为什么 traceM 并不总是在 Haskell 中给出输出?
问题描述
我有以下函数,它接受Expr
并输出 a [Typing]
,我只是插入一个 traceM 来查看函数在特定表达式上的行为。但是,它没有按应有的方式打印,我想知道为什么。
表达式如下所示:
data Expr = Vi Int
| Vb Bool
| Vv Name
| App Expr Expr
| Lam Name Typ1 Expr
deriving(Generic, Eq)
我正在运行的示例是这个:
(App (App (Lam "x" dyn (Lam "y" dyn (Vv "x"))) (Vv "f")) (App (Vv "f") (Vv "x")))
代码在这里。我不确定所有这些是否相关,但我试图打印进入“应用程序”案例时会发生什么。所以我用 traceM 看看在这种情况下会发生什么。
infer :: Expr -> [Typing]
infer expr = evalState (go expr) 0 where
go = \case
(Vi _) -> do
return [([], CInt)]
Vb _ -> do
return [([], CBool)]
(Vv x) -> do
v <- fresh
return [([(x, v)], v)]
(Lam x _ f) -> do
lst <- go f -- list of all possile typings
forM lst $ \(gamma, ty_e) -> do
case lookup x gamma of
Just typ -> do
let v = CArr typ ty_e
return (filter (\a -> x /= fst a) gamma, v)
Nothing -> do
v <- fresh
return (gamma , (CArr v ty_e))
(App m1 m2) -> do
(m1list, m2list) <- liftM2 (,) (go m1) (go m2)
traceM (show m2 ++ " - " ++ show m2list ++ " \n ")
traceM (show m1 ++ " - " ++ show m1list)
traceM (show "app " ++ show (App m1 m2))
fmap concat . forM m1list $ \(lam_env, t) -> do
case t of
CArr t1 t2 -> do
let (m2env, m2types) = unzip m2list
u' <- pleaseUnifyList (get_conj_elts t1) m2types
-- traceM (show "list" ++ show u')
-- traceM (show "possible empty list" ++ show (lam_env .+. solsum m2env, t2) )
return $ case u' of
Right u -> [ substituteTyping u (lam_env .+. solsum m2env, t2) ]
Left _ -> []
_ -> do
fmap concat . forM m2list $ \(app_env, s2) -> do
(t1, t2) <- liftM2 (,) fresh fresh
solve_all [t !> (t1 .~> t2), s2 .< t1, s2 !~ t1] lam_env app_env t2
当我运行此代码时,我得到以下信息:
"app "(λx:*.λy:*.x) f
λx:*.λy:*.x - [([],0 -> 1 -> 0)]
f - [([("f",2)],2)]
"app "f x
f - [([("f",3)],3)]
x - [([("x",4)],4)]
这段代码应该为每个 App 构造函数打印“app”。此表达式中有三个 App 构造函数,但它只打印两次。特别是,我缺少最外层的构造函数。这怎么可能?
编辑
infer :: Expr -> [Typing]
infer expr = evalState (go expr) 0 where
go = \case
(Vi _) -> do
return []
Vb _ -> do
return []
(Vv x) -> do
return []
(Lam x f) -> do
return []
(App m1 m2) -> do
(m1list, m2list) <- liftM2 (,) (go m1) (go m2)
traceM (show m2 ++ " - " ++ show m2list ++ " \n ")
traceM (show m1 ++ " - " ++ show m1list)
traceM (show "app " ++ show (App m1 m2))
return []
删除大部分代码并运行上面的代码后,根本没有打印出来。在语法上,Lam Name Typ1 Expr
应修改为Lam Name Expr
.
解决方案
推荐阅读
- response - SteamedResponse 在其他服务器上的流明中不起作用
- postgresql - postgres的pgAdmin4登录问题
- python - 获取转换后逻辑回归最重要特征的名称
- mysql - 删除 Select Inner Join 查询结果
- apache-kafka - 仅在 Kafka Connect 中看到 1 个工作人员
- sequelize.js - SequelizeDatabaseError:无法打开引用的表“成员”
- google-apps-script - 通过脚本在相关下拉列表/数据验证中设置默认列表值
- react-native - 反应原生的可读流
- google-bigquery - 如何从一列中提取逗号分隔值并将它们分别放在 Google Data Studio 中的单独列中?
- scala - 为什么 JVM 在不同的机器上需要不同的堆栈大小来编译程序?