【问题标题】:specialization in type classes using ghc使用 ghc 专门研究类型类
【发布时间】:2009-06-05 13:01:03
【问题描述】:

如何让 genOut/String 触发?

module IOStream where

import System.IO
import System.IO.Unsafe

class Out a where
  out :: a → String

instance Show a ⇒ Out a where
  out = show

outString :: String → String
outString = id
{-# RULES "genOut/String" out = outString #-}

infixl 9 <<, ≪
(≪), (<<) :: Out a ⇒ IO Handle → a → IO Handle
(<<)= (≪)
h ≪ a = do
  s ← h
  hPutStr s $ out a
  return s

cout, cin, cerr :: IO Handle
cout = return stdout
cin  = return stdin
cerr = return stderr

endl :: String
endl = "\n"

--infixr 9 ∘ °
(∘) = (.)
(°) = flip (∘)

module Main where

import System.IO
import IOStream

foreign import ccall "pi.h f_" f_ :: IO Double

main :: IO Int
main = do
  --putStrLn . show =<< f_

--  ((≪ endl) . (cout ≪)) =<< f_ 
  (cout ≪) ° (≪ endl) =<< f_
  return 0

编译链接:

cetin@unique:~/lab/c/linking/demo$ ghc --version
The Glorious Glasgow Haskell Compilation System, version 6.10.2
cetin@unique:~/lab/c/linking/demo$ ghc -fglasgow-exts -O2 -ddump-simpl-stats -XUndecidableInstances -O2 iostream.hs main.hs pi_v2.o -o hsex2

==================== FloatOut stats: ====================
0 Lets floated to top level; 1 Lets floated elsewhere; from 3 Lambda groups



==================== FloatOut stats: ====================
0 Lets floated to top level; 0 Lets floated elsewhere; from 5 Lambda groups



==================== Grand total simplifier statistics ====================
Total ticks:     184

40 PreInlineUnconditionally
45 PostInlineUnconditionally
24 UnfoldingDone
8 LetFloatFromLet
4 EtaReduction
57 BetaReduction
6 KnownBranch
11 SimplifierDone



==================== FloatOut stats: ====================
0 Lets floated to top level; 0 Lets floated elsewhere; from 1 Lambda groups



==================== FloatOut stats: ====================
3 Lets floated to top level; 0 Lets floated elsewhere; from 1 Lambda groups



==================== Grand total simplifier statistics ====================
Total ticks:     218

42 PreInlineUnconditionally
57 PostInlineUnconditionally
33 UnfoldingDone
9 LetFloatFromLet
1 EtaReduction
66 BetaReduction
10 KnownBranch
12 SimplifierDone

结果:

cetin@unique:~/lab/c/linking/demo$ ./hsex2
3.141592653589793"\n"cetin@unique:~/lab/c/linking/demo$ 

预期:

cetin@unique:~/lab/c/linking/demo$ ./hsex2
3.141592653589793
cetin@unique:~/lab/c/linking/demo$ 

我怎样才能触发该规则?

【问题讨论】:

  • 天哪,你对那些 Unicode 字符玩得太开心了,不是吗? :)
  • 呵呵,和我和他们一起经历的其他一些小冒险相比,这算不了什么^_^" ...我爱他们^o^!!

标签: haskell rules specialization ghc typeclass


【解决方案1】:

看起来你想要overlapping instances,因为你想要一个与instance Show a =&gt; Out a不同的instance Out String,它与它重叠。

{-# LANGUAGE FlexibleInstances, TypeSynonymInstances #-}
{-# LANGUAGE OverlappingInstances, UndecidableInstances #-}
class Out a where out :: a -> String
instance Out String where out = id
instance (Show a) => Out a where out = show

一般建议是避免使用重叠实例和不可判定实例,除非确实有必要,因为它们对类型检查所做的更改是不可移植的,并且可能导致其他问题。


编辑

在实现方面,为类的每个实例考虑字典。 &lt;&lt; 将获得 Out 实例的字典,预计将用作隐藏参数。由于正在从那里向上查找out,因此您的RULE 没有开火的空间。如果 out 不在类型类中,并且是从非多态函数调用的,那么我希望 RULE 匹配,但事实上,它不起作用也就不足为奇了。

RULE/SPECIALIZE 仅用于优化,您的代码不应改变行为,如果它们触发或不触发。

我花了一段时间才意识到你在做什么……你确实意识到 Haskell 不是 C++,对吧?多态性的使用方式完全不同。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-08-13
    • 2013-06-02
    • 1970-01-01
    • 2014-11-24
    • 2014-04-27
    • 1970-01-01
    • 1970-01-01
    • 2010-10-22
    相关资源
    最近更新 更多