2016-08-31 3 views
4

Ich verstehe nicht, warum die folgende Übung „Werke“ in Haskell Programmierung von First Principles:Teil Anwendung von Daten Konstruktor

type Subject = String 
type Verb = String 
type Object = String 

data Sentence = 
    Sentence Subject Verb Object 
    deriving (Eq, Show) 

s1 = Sentence "dogs" "drool" 
s2 = Sentence "Julie" "loves" "dogs" 

Laden der in GHCI zeigt, dass es ganz gut typechecks, aber warum ist dass die Definition von s1 überhaupt Sinn macht? Ich bin immer noch sehr neu in Haskell, also zuerst dachte ich, das war, weil Haskell in s1 implizit ließ die Object Zeichenfolge leer sein. Aber dann ...

*Main> s1 

<interactive>:13:1: 
    No instance for (Show (Object -> Sentence)) 
     arising from a use of `print' 
    Possible fix: 
     add an instance declaration for (Show (Object -> Sentence)) 
    In a stmt of an interactive GHCi command: print it 

Ich lerne immer noch, wie diese Fehlermeldungen richtig zu interpretieren, also bitte bitte mit mir. Aber kann jemand erklären, was No instance for (Show (Object -> Sentence)) bedeutet? Genauer gesagt, wie funktioniert das Auslassen der Object Zeichenfolge in s1 in dieser (Object -> Sentence) Sache?

Ich bin sicher, das ist dumm einfach, aber ich glaube nicht, das Buch mir dies durch diesen Punkt zu verstehen, ausgestattet hat ...

+4

Look up Funktion currying und im Kopf behalten: Wenn Sie explizit wollen die Unterscheidung zwischen Subjekten und Objekten sehen, können Sie Object auf einen Typ mit einem Datentyp Konstruktor MkObject konvertieren Datenkonstruktoren wie 'Sentence' werden ähnlich behandelt wie reguläre Funktionen. – Alec

Antwort

8

aber warum ist es, dass die Definition von s1 sogar Marken Sinn?

Wie @Alec erwähnt, heißt es Curry. Eine Möglichkeit, um zu sehen, was los ist, ist zu haben GHCI Ihnen sagen, was die Art der s1 ist:

ghci> :t s1 
s1 :: Object -> Sentence 

So s1 ist eine Funktion ein Object zu einem Sentence nehmen. Eine weitere Möglichkeit, darüber nachzudenken, ist mit der Definition zu starten:

s1 = Sentence "dogs" "drool" 

und mit equational Argumentation gelten beide Seiten auf einen Wert x:

s1 x = Sentence "dogs" "drool" x 

Also, wenn Sie anrufen s1 x es ist das gleiche wie der Aufruf von Sentence mit Die ersten beiden Funktionsargumente, fest codiert auf "dogs" und "drool" und x, werden das dritte Argument der Sentence-Funktion.

kann jemand erklären, was "No instance for (Show (Object -> Sentence))" bedeutet?

Wenn Sie etwas in GHCI bewerten, ist es im Grunde das gleiche wie fragen Haskell print es. Das heißt,

ghci> 3+4 

ist das Gleiche wie:.

ghci> print (3+4) 

(Diese Regel gilt nicht für IO-Aktionen wie getLine oder sogar print selbst in diesen Fällen Haskell läuft nur die IO- Aktion.)

Um print etwas muss es eine Show-Instanz für den Typ sein. Aber wie wir oben gesehen haben, ist s1 eine Funktion des Typs Object -> Sentence, und es gibt keine vordefinierten Show-Instanzen für Funktionen.

Beachten Sie, dass es eine Show-Instanz für Sentence Werte gibt, weil Sie GHC gebeten haben, eins mit deriving (Eq, Show) abzuleiten. Also, wenn Sie an der GHCI Aufforderung:

ghci> Sentence "Julie" "loves" "dogs" 

Sie:

Sentence "Julie" "loves" "dogs" 

, weil Sie wirklich GHCI fragen print (Sentence "Julie" "loves" "dogs") zu laufen.

Beachten Sie, dass print sich als (link) definiert:

print x = putStrLn (show x) 

und der Aufruf von show ist der Grund, warum ein Wert, der eine Karte Instanz für sie, um es zu drucken definiert haben muss.

+0

Sie können auch ': t Sentence' verwenden, um zu sehen, dass der Konstruktor den Typ' Subject -> Verb -> Object -> Sentence' hat; ': t Satz" Hunde "' hat Typ 'Objekt -> Verb -> Satz' usw. – chepner

0
No instance for (Show (Object -> Sentence)) 
    arising from a use of `print' 
Possible fix: 
    add an instance declaration for (Show (Object -> Sentence)) 
In a stmt of an interactive GHCi command: print it 

Zur Ergänzung @ ErikR Antwort: Sie werden sich vielleicht fragen, warum GHC nicht über eine integrierte Unterstützung für die Anzeige von Funktionen, dh im Gegensatz zu ganzen Zahlen und Strings, Funktionen haben keine Instanz für die Show typeclass (diese Begriffe werden später im Buch ausführlich erklärt, also keine Sorge, wenn Sie nicht verstehen, was eine Typklasse und eine Instanz ist), es sei denn, Sie definieren es explizit selbst. Als jemand, der Haskell lernt und aus einem objektorientierten Hintergrund kommt, fand ich es einfacher, eine Intuition für Typklassen zu bekommen, indem ich sie als Java-ähnliche Schnittstellen betrachtete.

Also, warum gibt es keine Show Insance für Funktionen? Die Haskell wiki bietet zwei Antworten:

1.Practically, GHC keine Spur von Variablennamen halten, das heißt, die folgenden sind die gleichen für den Compiler:

addOne num = num + 1 
f x = x + 1 
f y = y + 1 

Zusätzlich Funktionen optimiert werden können, beispielsweise können folgende äquivalente Darstellungen haben

f x = x - x + x 
f x = x 

2.Theoretically, eine Funktion, die durch ihren Graphen definiert ist, das heißt, die Menge von (Eingang, Ausgang) -Paare. z.B. für

f x = x + x 

die Paare sind (1,2), (2,4) usw. Somit Funktionen mit der gleichen Grafik sind identisch GHC-weise, zB

f x = x + x 
g y = 2 * y 

aber würden Sie erwarten Sie show f und show g anders zu sein, vor allem, wenn Sie signifikante Variablennamen anstelle von x und y verwenden.

Das heißt, können Sie eine Pragma verwenden (eine Erweiterung für den GHC-Compiler, dass einige Funktionen, die über die Haskell Sprachstandard enthält), die nur die Funktion des Typs zeigen würde, wie in this answer erklärt:

{-# LANGUAGE ScopedTypeVariables #-} 

import Data.Typeable 

instance (Typeable a, Typeable b) => Show (a->b) where 
    show _ = show $ typeOf (undefined :: a -> b) 

Dies wird Ihnen

> s1 
[Char] -> Sentence 

erhalten, da Object ein Alias ​​von String ist (mit dem type Schlüsselwort, String ist selbst ein Alias ​​für [Char]).

newtype Object = MkObject String deriving (Eq, Show) 

s1 = Sentence "dogs" "drool" 
s2 = Sentence "Julie" "loves" (MkObject "dogs") 

und voilà

> s1 
Object -> Sentence 
Verwandte Themen