<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<meta name="Generator" content="Microsoft Exchange Server">
<!-- converted from text --><style><!-- .EmailQuote { margin-left: 1pt; padding-left: 4pt; border-left: #800000 2px solid; } --></style>
</head>
<body>
<div>
<div>I feel so unbelievably ignorant now. I thought with all the IORefs in the type checking process that zonking did this in these refs. Somehow I started thinking that some of these remained in SDocs, not thinking showSDoc is pure and results in a String,
which holds no IORefs.</div>
<div><br>
</div>
<div>Does this mean that for the idType to come out correctly I should also zonk (AND BIND) the Id-value I return?</div>
<div><br>
</div>
<div>Ph.</div>
<div><br>
</div>
<div><br>
</div>
<div><br>
</div>
<div><br>
</div>
<div>
<div style="font-size:75%; color:#575757">Sent from Samsung Mobile</div>
</div>
<br>
<br>
<br>
-------- Original message --------<br>
From: Simon Peyton-Jones <simonpj@microsoft.com> <br>
Date: 30/08/2013 18:25 (GMT+01:00) <br>
To: "Holzenspies, P.K.F. (EWI)" <p.k.f.holzenspies@utwente.nl>,glasgow-haskell-users@haskell.org
<br>
Subject: RE: Question about correct GHC-API use for type checking (or zonking, or tidying)
<br>
<br>
<br>
</div>
<font size="2"><span style="font-size:10pt;">
<div class="PlainText">Haskell is a *functional* language. Consider<br>
<br>
say $ " pre-zonk: " ++ pp all_expr_ty<br>
zonkTcType all_expr_ty<br>
say $ " post-zonk: " ++ pp all_expr_ty<br>
<br>
pp is a pure function; it is given the same input both times, so of course it produces the same output.<br>
<br>
If you collect the result of zonkTcType you might have better luck, thus:<br>
<br>
say $ " pre-zonk: " ++ pp all_expr_ty<br>
zonked_expr_ty <- zonkTcType all_expr_ty<br>
say $ " post-zonk: " ++ pp zonked_expr_ty<br>
<br>
Zonking walks over a type, returning a new type in which unification variables are replaced by the types they unified to.<br>
<br>
Hope this helps<br>
<br>
Simon<br>
<br>
| -----Original Message-----<br>
| From: Glasgow-haskell-users [<a href=""></a>mailto:glasgow-haskell-users-<br>
| bounces@haskell.org] On Behalf Of p.k.f.holzenspies@utwente.nl<br>
| Sent: 29 August 2013 14:42<br>
| To: glasgow-haskell-users@haskell.org<br>
| Subject: Question about correct GHC-API use for type checking (or<br>
| zonking, or tidying)<br>
| <br>
| Dear GHC-ers,<br>
| <br>
| I'm working on building an interactive environment around the<br>
| composition of expressions. Users can type in (i.e. give strings of)<br>
| expressions and can then use these expressions to produce other<br>
| expressions. I'm close to having a working GHC-API binding for this. The<br>
| resulting types, however, still contain some things I don't quite<br>
| understand. Any help would be appreciated.<br>
| <br>
| Below, I've included the function exprFromString which should parse,<br>
| rename and typecheck strings to Id-things and give their type (although,<br>
| ideally, the idType of said Id-thing should be the same as the type<br>
| returned). This function lives in the IA (InterActive) monad; a monad<br>
| that is a GhcMonad and can lift monadic computations in TcM into itself<br>
| using liftTcM (which uses the initTcPrintErrors and<br>
| setInteractiveContext functions similarly to TcRnDriver.tcRnExpr).<br>
| <br>
| Near the end of the function, debugging output is produced. This output<br>
| confuses me slightly. Here is the output for the three inputs "map (+1)<br>
| [1..10]", "5" and "\\x -> x":<br>
| <br>
| <br>
| map (+1) [1..10]<br>
| pre-zonk: forall b. (GHC.Enum.Enum b_i, GHC.Num.Num b_i) => [b_i]<br>
| post-zonk: forall b. (GHC.Enum.Enum b_i, GHC.Num.Num b_i) => [b_i]<br>
| idType: [b_c]<br>
| tidied: forall b. (GHC.Enum.Enum b_i, GHC.Num.Num b_i) => [b_i]<br>
| 5<br>
| pre-zonk: forall a. GHC.Num.Num a_d => t_c<br>
| post-zonk: forall a. GHC.Num.Num a_d => t_c<br>
| idType: a_b<br>
| tidied: forall a. GHC.Num.Num a_d => t_c<br>
| \x -> x<br>
| pre-zonk: forall t. t_e<br>
| post-zonk: forall t. t_e<br>
| idType: forall t. t -> t<br>
| tidied: forall t. t_e<br>
| <br>
| <br>
| The zonking and tidying part of the type-checking process are still a<br>
| bit unclear to me and I suspect the problems arise there. It looks to me<br>
| that the type variables in the quantifications are different ones from<br>
| those in the pi/rho-types. I had expected the types to only contain the<br>
| variables over which they are quantified, so e.g. in the map-example, I<br>
| had expected "forall b . (GHC.Enum.Enum b, GHC.Num.Num b) => [b]"<br>
| <br>
| Can anyone explain what I'm missing?<br>
| <br>
| Regards,<br>
| Philip<br>
| <br>
| <br>
| <br>
| <br>
| <br>
| exprFromString :: String -> IA (Id,Type)<br>
| exprFromString str = do<br>
| dfs <- getDynFlags<br>
| let pp = showSDoc dfs . ppr<br>
| pst <- mkPState dfs buf <$> newRealSrcLoc<br>
| <br>
| {- Parse -}<br>
| (loc,rdr_expr) <- case unP parseStmt pst of<br>
| PFailed span err -> throwOneError (mkPlainErrMsg dfs span err)<br>
| POk pst' (Just (L l (ExprStmt rdr_expr _ _ _))) -> do<br>
| logWarningsReportErrors (getMessages pst')<br>
| return (l,rdr_expr)<br>
| POk pst' thing -> throw $ maybe EmptyParse (const<br>
| NonExpressionParse) thing<br>
| liftTcM $ do<br>
| fresh_it <- freshName loc str<br>
| <br>
| {- Rename -}<br>
| (rn_expr, fvs) <- checkNoErrs $ rnLExpr rdr_expr<br>
| <br>
| {- Typecheck -}<br>
| let binds = mkBinds fresh_it rn_expr fvs<br>
| <br>
| (((_bnds,((_tc_expr,res_ty),id)),untch),lie) <- captureConstraints .<br>
| captureUntouchables $<br>
| tcLocalBinds binds ((,) <$> tcInferRho rn_expr <*> tcLookupId<br>
| fresh_it)<br>
| ((qtvs, dicts, _bool, _evbinds), lie_top) <- captureConstraints $<br>
| simplifyInfer True False [(fresh_it, res_ty)] (untch,lie)<br>
| <br>
| let all_expr_ty = mkForAllTys qtvs (mkPiTypes dicts res_ty)<br>
| say str<br>
| say $ " pre-zonk: " ++ pp all_expr_ty<br>
| zonkTcType all_expr_ty<br>
| say $ " post-zonk: " ++ pp all_expr_ty<br>
| say $ " idType: " ++ pp (idType id)<br>
| say $ " tidied: " ++ pp (tidyTopType all_expr_ty)<br>
| <br>
| return (id,all_expr_ty)<br>
| where<br>
| say = liftIO . putStrLn<br>
| buf = stringToStringBuffer str<br>
| freshName loc str = (\u -> mkInternalName u name loc) <$> newUnique<br>
| where<br>
| name = mkOccNameFS varName $ fsLit $ "it" ++ show (lineOf loc)<br>
| isVarChar c = isAlphaNum c || c == '_' || c == '\''<br>
| lineOf (RealSrcSpan s) = srcSpanStartLine s<br>
| lineOf _ = -1<br>
| <br>
| mkBinds :: Name -> LHsExpr Name -> FreeVars -> HsLocalBinds Name<br>
| mkBinds nm e@(L l _) fvs = HsValBinds $ ValBindsOut [(NonRecursive,<br>
| unitBag the_bind)] []<br>
| where<br>
| the_bind = L l (mkTopFunBind (L l nm) [mkMatch [] e<br>
| emptyLocalBinds]) { bind_fvs = fvs }<br>
| <br>
| <br>
| <br>
| _______________________________________________<br>
| Glasgow-haskell-users mailing list<br>
| Glasgow-haskell-users@haskell.org<br>
| <a href="http://www.haskell.org/mailman/listinfo/glasgow-haskell-users">http://www.haskell.org/mailman/listinfo/glasgow-haskell-users</a><br>
</div>
</span></font>
</body>
</html>