2014-10-02 4 views
16

Ich habe versucht, herauszufinden, wie MVar arbeitet, und ich auf dieses Stück Code kam:Was sind Hashes (#) in der Quelle der Bibliothek?

-- |Create an 'MVar' which is initially empty. 
newEmptyMVar :: IO (MVar a) 
newEmptyMVar = IO $ \ s# -> 
    case newMVar# s# of 
     (# s2#, svar# #) -> (# s2#, MVar svar# #) 

Neben mit newMVar, ist es auch mit Hashes (#) übersät zum Verwechseln gegenseitig rekursiv zu sein.

Zwischen den beiden kann ich nicht herausfinden, wie es funktioniert. Ich weiß, dass dies im Grunde nur ein Pseudo-Konstruktor für mVar ist, aber der Rest des Moduls (der größte Teil der Bibliothek tatsächlich) enthält sie, und ich kann nichts auf ihnen finden. Das googeln von "Haskell Hashs" ergab nichts Relevantes.

Antwort

18

Sie sind (buchstäblich) magische Hashes. Sie unterscheiden GHC-Primitive wie Addition, Unboxed-Typen und Unboxed-Tupel. Sie können sie mit

{-# LANGUAGE MagicHash #-} 

Jetzt aktivieren Schreiben können Sie die Stubs import, die Sie mit

import GHC.Exts 

unboxed :: Int# -> Int# -> Int# 
unboxed a# b# = a# +# b# 

boxed :: Int -> Int -> Int 
boxed (I# a#) (I# b#) = I# (unboxed a# b#) 

nutzen sie lassen diese tatsächlich ist irgendwie nette, wenn man darüber nachdenkt, indem Sie die magische und strenge Primitiven Einwickeln So können wir die faulen Int s und Char s einheitlich auf Laufzeitsystem-Ebene behandeln.

Da Grundelemente nicht eingerahmt sind, werden sie auf der Art-Ebene getrennt. Das bedeutet, dass Int# nicht die Art * wie normale Typen haben, was bedeutet, auch so etwas wie

kindClash :: Int# -> Int# 
kindClash = id -- id expects boxed types 

nicht kompiliert.

Um weiter zu Ihrem Code, newMVar enthält einen Aufruf an einen Compiler-Primitive in GHC, um eine neue veränderbare Variable zuweisen. Es ist nicht so sehr rekursiv wie ein dünner Wrapper über einen Compiler-Aufruf. Es gibt auch etwas Dunkelheit, die sich an den Ecken dieser Funktion sammelt, da wir IO als perverse Zustands-Monade behandeln, aber schauen wir uns das nicht genau an. Ich mag meine geistige Gesundheit zu sehr.

Ich verwende keine Primitiven im Code des Alltags, noch sollten Sie. Sie kommen bei der Implementierung von verrückten optimierten Hotspots oder in der Nähe primitiver Abstraktionen wie dem, was Sie gerade sehen.

+0

Vielen Dank. Für meine Zwecke, Bibliotheksauszüge zu verstehen, kann ich sie im Wesentlichen ignorieren und nur über die Typen nachdenken, denen sie zugeordnet sind? – Carcigenicate

+1

@Carcigenicate So ziemlich, ja. – bheklilr

+0

@Carcigenicate Ich würde sagen, Sie können die Dokumentation für die Primitiven lesen, wenn Sie wirklich neugierig sind, ich glaube nicht, dass Sie eine Tonne von ihnen jedoch gewinnen würden. – jozefg

Verwandte Themen