2017-03-14 42 views
3

我想實現保證導出類似功能集的模塊。什麼是接口的haskell等價物?

爲了舉例:假設我想翻譯一個詞。每個單詞都是從源語言(比如說English)映射到目標語言(假設爲SpanishRussian)。

我的主應用程序將導入西班牙語和俄語的模型,並選擇默認模型,俄羅斯。我想確保,每個模型有:

  • 功能translateToken :: String -> String
  • 所處的具體行爲實現的功能translatePhrase :: String -> String

我該怎麼做?

編輯,關於李的回答是: 如何創建數據類型與包含使用衛士功能記錄語法?

-- let's suppose I want to use a function with guards in a record. 
-- how can and should i define that? 

data Model = Model { translateToken :: String -> String} 

-- idea 1) should I define the functions separately, like this? 
-- how do I do this in a way that does not clutter the module? 
f l 
    | l == "foo" = "bar" 

main :: IO() 
main = print $ translateToken x "foo" 
    where 
    x = Model {translateToken=f} 
    -- idea 2) define the function when creating the record, 
    -- despite the syntax error, this seems messy: 
    -- x = Model {name=(f l | l == "foo" = "bar")} 

-- idea 3) update the record later 

回答

15

您可以創建一個包含所需功能的類型,例如

data Model = Model { translateToken :: String -> String, 
        translatePhrase :: String -> String } 

然後爲西班牙語和俄語創建值。

+1

我很好奇,爲什麼鍵入記錄而不是類型類? –

+7

@MichalCharemza因爲當你使用一個用作Java接口的類型'C'時,你很快就會被'C'不是一個類型的事實觸發,並開始定義''''周圍的存在類型'data T = forall t。 C t => T t'。這是一個衆所周知的Haskell [反模式](https://lukepalmer.wordpress.com/2010/01/24/haskell-antipattern-existential-typeclass/)。注意:我大多同意盧克帕爾默的看法,認爲這往往是矯枉過正的,並沒有獲得任何東西的w.r.t.使用帶有功能的基本記錄。然而,在某些特定情況下,我確實認爲「反模式」是合理的。 – chi

+2

@MichalCharemza - 我認爲這種方法更簡單,因爲您不需要爲每個翻譯實例(即'SpanishTranslation','RussianTranslation')創建一個新類型。另一個優點是你可以將記錄放入集合中,並將它們一起操作,這對於類型類別來說很尷尬。我也認爲這更接近於OO語言中接口的使用,其中行爲與接收器而不是類型耦合。 – Lee

2

這將是typeclasses。從Learn You a Haskell: 「類型類更像是接口」

你會定義自己的類型類(未經測試):

class Translation a where 
    translateToken :: a -> String -> String 
    translatePhrase :: a -> String -> String 

並執行它作爲也

instance Translation Spanish where 
    translateToken = spanishTranslateToken 
    translatePhrase = spanishTranslatePhrase 

Real Word Haskell on typeclasses

+0

一個小錯字,它應該是'實例翻譯西班牙語哪裏'而不是'實例西班牙語翻譯哪裏' – jakubdaniel

+0

@ jd823592多麼愚蠢的錯誤 - 修復。謝謝。 –

+0

@FrankSchmitt正如我在評論李的回答時所寫的那樣:如果我像你一樣仔細閱讀文獻,那就是我的回答。謝謝你,我很感激!但是,我會接受Lee的答案,因爲「類型類是爲了超載,而不是數據抽象。」 – inktrap

-3

A class,有時被稱爲「類型類」。儘管如此,不要將它與通常的OO類混淆,Haskell類沒有數據,並且通常沒有實現(通用默認值除外)。

+1

不是我的失望,但是你的意思是「[classes]通常沒有實現(除了一般的默認值)「?你的意思是許多實現是自動派生的而不是手寫的? – erisco

+0

我的意思是類只定義了函數的類型,它們沒有定義函數本身。這是不同的C++類,它往往但不總是有這兩種類型和實現 – Clinton

相關問題