基于函数结果类型的优化

时间:2017-02-18 08:17:30

标签: haskell optimization ghc

下面是一个可能很愚蠢的例子,但我认为解决这个问题将解决我的另一个问题,详细in this question

我想用这个签名写一个函数:

myread :: (Read a) => String -> a

这样myread = reada ~ Int除外,在这种情况下myread _ = 0

显然这个功能本身很傻,但关键是我想根据返回类型进行优化。

重写规则,或者这里的一切都没问题。对于我的实际问题,如果解决方案是重写规则,那么在没有触发的情况下并不重要,但我想要的答案是至少给出一个它的例子。

2 个答案:

答案 0 :(得分:1)

如果您记得规则的左侧是表达式上下文,不,您可以直接使用重写规则(可能)以明显的方式执行此操作em>在模式上下文中。特别是,左侧的类型应用程序是完全有效的。

{-# LANGUAGE TypeApplications #-} 

module A where 

{-# INLINE [1] myread  #-}
{-# RULES "myread" forall s . myread @Int s = 0 #-}

myread :: Read a => String -> a 
myread = read 

即使没有类型应用程序,以下内容也完全有效(但可能不是一般的,例如,如果输出类型为f a,并且您希望仅{{1}优化{{1} },你不能拥有f):

.. = (result :: [ _ ])

作为一个例子,使用

{-# RULES "myread" forall s . myread s = (0 :: Int) #-}

规则触发的证据总是要看核心,当然(省略不相关的位):

module B where 

import A 

fun :: String -> String -> (Int, Bool) 
fun x y = (myread x, myread y) 

请注意,这只是一个评论,而不仅仅是因为我不确定目标是什么,但代码不适合评论。

答案 1 :(得分:0)

如何使用不可判定的实例定义新类?

{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE UndecidableInstances #-}

class MyRead a where
  myread :: String -> a

instance {-# OVERLAPPABLE #-} Read a => MyRead a where
  myread = read

instance MyRead Int where
  myread = const 0

main = do
  print $ (myread "True" :: Bool) -- True
  print $ (myread "\"string\"" :: String) -- "string"
  print $ (myread "12" :: Int) -- 0