التخصص في فصول النوع باستخدام GHC
-
11-09-2019 - |
سؤال
كيف يمكنني صنع نيران الجنول / السلسلة؟
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$
كيف يمكنني إطلاق النار على هذه القاعدة؟
المحلول
يبدو أنك تريد مثيلات متداخلة, ، كما تريد أن يكون لديك instance Out String
وهو مختلف instance Show a => Out a
الذي يتداخله.
{-# 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
التوصية العامة هي تجنب استخدام المثيلات المتداخلة والحالات غير القابلة للتوحيد إلا حقا ضروري، حيث أن التغييرات في Typechecking أنها تجعلها غير محمولة ويمكن أن تسبب مشاكل أخرى.
يحرر
التنفيذ الحكيم، التفكير في القاموس لكل حالة من الفصل. <<
سيتم منح القاموس على سبيل المثال Out
أنه من المتوقع أن تستخدم معلمة مخفية. حيث out
يجري النظر من هناك، لا يوجد مجال لك RULE
لإطلاق النار. إذا out
لم تكن في Typeclass، وتم استدعاء من وظيفة غير متعددة الجنسيات، ثم أتوقع RULE
للمطابقة، ولكن كما هو الحال، ليس من المستغرب أنه لا يعمل.
RULE
/SPECIALIZE
من المفترض أن تكون التحسينات فقط، ويجب عدم تغيير الكود الخاص بك السلوك إذا فعلوا أو لا ينطلقون.
استغرق الأمر مني بعض الوقت لإدراك ما كنت تفعله ... أنت تدرك أن Haskell ليس C ++، أليس كذلك؟ الطرق التي يستخدمها تعدد الأشكال مختلفة تماما.