2012-08-15 35 views
1

我試圖使這種數據類型的Functor一個實例:是否無法創建此數據類型的Functor實例?

data Fraction = Frac Integer Integer deriving Show 

但是,定義它像這樣將無法工作:

instance Functor Fraction where 
    pure = Frac 1 1 
    fmap f (Frac a b) = Frac (f a) (f b) 

這個功能,我會更喜歡數據是Functor的一個實例。但是,這是否違反了一些法律,因爲Fraction的參數總是兩個Integers

我總是可以自己寫fmap,並避免Functor聲明,但我試圖更熟悉語言,所以任何幫助將不勝感激!

回答

8

是的,你不能定義一個函數而沒有一個類型變量來「聲明」聲明(或者更正式地說:函子實例必須被定義爲* -> *)。 fmap的簽名是fmap :: (a -> b) -> f a -> f b,所以爲了滿足該合同,必須有可能爲該功能選擇任何類型ab

你當然也可以只是重新定義Fraction是這樣的:

data Fraction a = Frac a a deriving Show 

...或者你可以使用分數/有理數現有的數據類型Data.Ratio,不形成函子,因爲沒人認爲有這樣一個實例是有用的(反正你會用它什麼?),但至少你會使用一個已經建立的和現有的數據結構。

+0

我正在建立一個小型圖書館進行某種鍛鍊。 'fmap'可能實際上甚至沒有用處......我想這是一個很好的觀點。 但是,無論如何,謝謝你的澄清!這幫助了我一堆。 – 2012-08-15 18:58:59

+1

我看到的'fmap'的唯一用途是它可以用於將分子和分母同時用一些常見的值進行劃分,但這很容易做到。模式匹配。另外,我認爲最大的缺點是沒有明智的方法來實現'Fraction'的'pure',即使它僅限於使用'Integer'。爲什麼數字「1/1」特殊?爲什麼不用'0/12'或'42/1'?但是你可能對'Monoid'類和''algebra''(http://hackage.haskell.org/package/algebra)包中的各個類感興趣。 – dflemstr 2012-08-15 19:03:48

+0

(對於代數包,您可能需要單擊以前的版本才能閱讀文檔,因爲最新版本會出現故障並缺少文檔) – dflemstr 2012-08-15 19:05:04

相關問題