2017-10-05 8 views
12

मैं एक सहकर्मी Free दिखा रहा था जब मैं एक जिज्ञासु जीएचसी व्यवहार में भाग गया, मैं वास्तव में समझ में नहीं आता। यहाँ एक सरल, काल्पनिक कार्यक्रम है कि typechecks है:जब मैं एक असंबंधित परिभाषा जोड़ता हूं तो मुझे इस प्रोग्राम में एक प्रकार की त्रुटि क्यों मिलती है?

import Prelude hiding (readFile, writeFile) 
import Control.Monad.Free 
import Data.Functor.Sum 

data FileSystemF a 
    = ReadFile FilePath (String -> a) 
    | WriteFile FilePath String a 
    deriving (Functor) 

data ConsoleF a 
    = WriteLine String a 
    deriving (Functor) 

data CloudF a 
    = GetStackInfo String (String -> a) 
    deriving (Functor) 

type App = Free (Sum FileSystemF (Sum ConsoleF CloudF)) 

readFile :: FilePath -> App String 
readFile path = liftF (InL (ReadFile path id)) 

writeFile :: FilePath -> String -> App() 
writeFile path contents = liftF (InL (WriteFile path contents())) 

मैं एक और परिभाषा जोड़ने की कोशिश की है, लेकिन यह बिल्कुल ठीक नहीं था:

writeLine :: String -> App() 
writeLine line = liftF (InR (WriteLine line())) 

समस्या यहाँ है कि मैं एक और InL याद आ रही थी। सही परिभाषा यह होनी चाहिए:

writeLine :: String -> App() 
writeLine line = liftF (InR (InL (WriteLine line()))) 

हालांकि, यह बात नहीं है। मेरे लिए अजीब बात यह है कि जीएचसी ने उत्पाद त्रुटि को जोड़ा जब मैंने अपनी पहली, गलत परिभाषा writeLine की।

/private/tmp/free-sandbox/src/FreeSandbox.hs:26:27: error: 
    • Couldn't match type ‘ConsoleF’ with ‘Sum ConsoleF CloudF’ 
     arising from a functional dependency between constraints: 
      ‘MonadFree 
      (Sum FileSystemF (Sum ConsoleF CloudF)) 
      (Free (Sum FileSystemF (Sum ConsoleF CloudF)))’ 
      arising from a use of ‘liftF’ at src/FreeSandbox.hs:26:27-66 
      ‘MonadFree 
      (Sum FileSystemF ConsoleF) 
      (Free (Sum FileSystemF (Sum ConsoleF CloudF)))’ 
      arising from a use of ‘liftF’ at src/FreeSandbox.hs:29:18-48 
    • In the expression: liftF (InL (WriteFile path contents())) 
     In an equation for ‘writeFile’: 
      writeFile path contents = liftF (InL (WriteFile path contents())) 
    | 
26 | writeFile path contents = liftF (InL (WriteFile path contents())) 
    |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 

/private/tmp/free-sandbox/src/FreeSandbox.hs:29:18: error: 
    • Couldn't match type ‘Sum ConsoleF CloudF’ with ‘ConsoleF’ 
     arising from a functional dependency between: 
      constraint ‘MonadFree 
         (Sum FileSystemF ConsoleF) 
         (Free (Sum FileSystemF (Sum ConsoleF CloudF)))’ 
      arising from a use of ‘liftF’ 
      instance ‘MonadFree f (Free f)’ at <no location info> 
    • In the expression: liftF (InR (WriteLine line())) 
     In an equation for ‘writeLine’: 
      writeLine line = liftF (InR (WriteLine line())) 
    | 
29 | writeLine line = liftF (InR (WriteLine line())) 
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 

दो त्रुटियों के दूसरे (लाइन 29 पर एक) समझ में आता है: विशेष रूप से, यह दो प्रकार त्रुटियों का उत्पादन किया। यह एक त्रुटि है जिसे मैं उम्मीद करूंगा। लेकिन लाइन 26 पर त्रुटि पूरी तरह से मुझे परेशान करता है। writeFile की परिभाषा सही है! writeLine की मेरी गलत परिभाषा को जोड़ने से writeFile पर कोई प्रभाव नहीं पड़ना चाहिए, है ना? क्या चल रहा है?

मैं इसे जीएचसी 8.0.2 और जीएचसी 8.2.1 पर पुन: उत्पन्न करने में सक्षम था। मैं जानना चाहता हूं कि यह जीएचसी में एक बग है (इसलिए मैं इसकी रिपोर्ट कर सकता हूं) या यदि यह मेरे कोड के साथ कोई समस्या है जिसे मैं समझ नहीं पा रहा हूं।

+6

ओह यह एक महान है। ध्यान दें कि यदि आपने गलत परिभाषा 'परिभाषा' परिभाषा _before_ अन्य परिभाषाओं को संदिग्ध त्रुटि गायब कर दिया है। :) – Alec

+4

मैंने इस समस्या को ट्रैक करने के लिए [जीएचसी ट्रैक # 14327] (https://ghc.haskell.org/trac/ghc/ticket/14327) खोला है। –

+0

यह समस्या एफडी से संबंधित प्रतीत होती है, क्योंकि 'लिफ्टएफ' विशेषज्ञता है :: फंक्शन एफ => एफ ए -> फ्री एफ ए 'अतिरिक्त त्रुटि से छुटकारा पाता है। शायद मुझे कुछ याद आ रही है। – Alec

उत्तर

संबंधित मुद्दे

 संबंधित मुद्दे