1

我想創建三個Haskell函數:a,bc如何創建返回函數的Haskell函數?

每個函數都有一個參數。這個論點是三個功能之一。

我想功能a有此行爲:

  • 如果參數功能a然後返回功能a
  • 如果參數是函數b,則返回函數b
  • 如果參數是函數c,則返回函數a

這裏是我的功能a渴望行爲的概括:

a a = a 
a b = c 
a c = a 

這裏是我的另外兩個函數的願望行爲:

b a = a 
b b = a 
b c = c 

c a = c 
c b = b 
c c = c 

創建後,我想以各種方式組成功能,例如:

a (c b) 
= a (b) 
= c 

如何創建這些功能?

+2

您必須使用一些數據標記該功能,以便您可以比較它們。也就是說,你不能使用普通函數。你需要把它們放在一個數據類型中,它也有一些可比的價值。 – 2012-03-16 22:58:02

+1

到目前爲止你做了什麼?你有沒有這些功能的簽名? – 2012-03-16 22:59:37

+3

你想通過實現這個來做什麼? – 2012-03-16 23:03:30

回答

16

由於您沒有給出如何觀察結果的標準,因此a = b = c = id滿足您的標準。但當然這不是你想要的。但是這個想法很重要:它不僅僅是你想要你的功能有什麼行爲,而是你如何去觀察這個行爲。

有一個最一般的模型,如果你允許的符號一定的自由度,並且通過使用代數數據類型得到這樣的:

data F = A | B | C 
    deriving (Eq, Show) -- ability to compare for equality and print 

infixl 1 % 
(%) :: F -> F -> F 
A % A = A 
A % B = C 
A % C = A 
B % A = A 
... 

等。不要說a b,你必須說A % B,但這是唯一的區別。您可以撰寫他們:

A % (C % B) 
= A % B 
= B 

,您可以通過部分應用(%)把它們變成功能:

a :: F -> F 
a = (A %) 

但你不能比較這a,作爲ehird說。這個模型與您指定的模型相同,只是看起來有些不同。

+4

你可以比較一下'a'很好:'實例Eq(F - > F)其中f == g = all(\ x - > fx == gx)[A,B,C]' – 2012-03-17 11:10:53

+0

@SjoerdVisscher,oh ,對,因爲它是有限的。我總是忘記這一點。 – luqui 2012-03-17 20:10:59

11

這是不可能的;您無法將功能與對方進行比較,因此無法檢查您的參數是否爲abc或其他。實際上,Haskell不可能讓你檢查兩個函數是否相同:因爲Haskell是引用透明的,所以用相同函數的兩個不同實現替代應該沒有任何作用。也就是說,只要您爲每個輸出提供相同的輸入,功能的確切實現應該無關緊要,並且儘管驗證\x -> x+x\x -> x*2是相同的功能很容易,但它是undecidable in general

此外,有沒有可能類型a可以有,如果是拿自己作爲一個參數(當然,id id類型,但id可以採取什麼作爲第一個參數 - 這意味着它不能在檢查它你想要的方式)。

如果你試圖用這個來實現某些東西(而不是僅僅因爲好奇而玩 - 當然很好),那麼你就必須以其他方式來完成。沒有具體的細節,很難確切地說明這將是什麼方式。

4

那麼,你可以像這樣做:

{-# LANGUAGE MagicHash #-} 

import GHC.Prim 
import Unsafe.Coerce 

此功能是從ehird的回答here

equal :: a -> a -> Bool 
equal x y = x `seq` y `seq` 
       case reallyUnsafePtrEquality# x y of 
       1# -> True 
       _ -> False 

現在,讓我們進入正題。請注意,您需要強制參數和返回值,因爲這些函數實際上沒有可能的類型,正如ehird指出的那樣。

a,b,c :: x -> y 
a x | unsafeCoerce x `equal` a = unsafeCoerce a 
    | unsafeCoerce x `equal` b = unsafeCoerce c 
    | unsafeCoerce x `equal` c = unsafeCoerce a 

b x | unsafeCoerce x `equal` a = unsafeCoerce a 
    | unsafeCoerce x `equal` b = unsafeCoerce a 
    | unsafeCoerce x `equal` c = unsafeCoerce c 

c x | unsafeCoerce x `equal` a = unsafeCoerce c 
    | unsafeCoerce x `equal` b = unsafeCoerce b 
    | unsafeCoerce x `equal` c = unsafeCoerce c 

最後,一些測試:

test = a (c b) `equal` c -- Evaluates to True 
test' = a (c b) `equal` a -- Evaluates to False 

EHH ...

+0

你可以用19個不安全的''不安全''做,但你可以用20嗎?! – luqui 2012-03-16 23:27:11

+0

@luqui:第20個'unsafeCoerce'正在隱藏[here](http://hpaste.org/65425) – danr 2012-03-16 23:34:17

+3

@luqui當然! 「真正的安全數量增加了一倍。 – 2012-03-16 23:35:14

0

如前所述,功能不能平等比較。如果你只是想要滿足代數定律的函數,那麼使它們都等於身份函數就會很好。

我希望您知道,如果您向Stack Overflow發佈與作業相關的問題,社區期望您可以將其識別爲此類。

+2

只有一個非常殘忍,非常無知,或者很不清楚的老師纔會把這當作一個家庭作業問題。 – 2012-03-17 07:21:00

+2

@丹伯頓:贊同。但如果它不是家庭作業,那麼地球上的這個問題從哪裏來? – 2012-03-17 19:31:55