سؤال

كيف يمكنني صنع نيران الجنول / السلسلة؟

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 ++، أليس كذلك؟ الطرق التي يستخدمها تعدد الأشكال مختلفة تماما.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top