簡體   English   中英

如何在沒有泛型類型參數的情況下定義泛型函數?

[英]How to define generic function without argument of generic type?

我現在正在閱讀“Haskell Book”的monoid部分,作者使用QuickCheck檢查幺半群定律。 在我自己寫完一些東西后,我有這個代碼:

module Main where

import Data.Monoid
import Test.QuickCheck

monoidAssoc :: (Eq m, Monoid m) => m -> m -> m -> Bool
monoidAssoc a b c = ((a <> b) <> c) == (a <> (b <> c))

monoidLeftId :: (Eq m, Monoid m) => m -> Bool
monoidLeftId a = (mempty <> a) == a

monoidRightId :: (Eq m, Monoid m) => m -> Bool
monoidRightId a = (a <> mempty) == a

type AssocCheck a = a -> a -> a -> Bool
type IdCheck a = a -> Bool

main :: IO ()
main = do
  quickCheck (monoidAssoc   :: AssocCheck (Maybe String))
  quickCheck (monoidLeftId  :: IdCheck (Maybe String))
  quickCheck (monoidRightId :: IdCheck (Maybe String))

  quickCheck (monoidAssoc   :: AssocCheck [String])
  quickCheck (monoidLeftId  :: IdCheck [String])
  quickCheck (monoidRightId :: IdCheck [String])

正如你所看到的, main函數有兩個幾乎相同的塊,我想減少到這樣的東西:

checkMonoid :: (Eq m, Monoid m) => m -> IO ()
checkMonoid = do
  quickCheck (monoidAssoc   :: AssocCheck m)
  quickCheck (monoidLeftId  :: IdCheck m)
  quickCheck (monoidRightId :: IdCheck m)


main :: IO ()
main = do
  checkMonoid :: Maybe String -> IO ()
  checkMonoid :: [String] -> IO ()

但這顯然不會起作用。 我想要的是以某種方式將類型傳遞給checkMonoid函數,因此quickCheck函數將知道必須生成哪些arbitrary數據。

這正是TypeApplication允許您執行的操作 - 您可以顯式傳遞m的類型。 那么你還需要ScopedTypeVariables ,以確保所有的m ,你在s checkMonoid是相同的,並且AllowAmbiguousTypes讓GHC知道你是罰款的事實, checkMonoid將是曖昧不用類型的應用程序。

{-# LANGUAGE TypeApplications, AllowAmbiguousTypes, ScopedTypeVariables #-}

-- ...

checkMonoid :: forall m. (Eq m, Monoid m, Show m, Arbitrary m) => IO ()
checkMonoid = do
  quickCheck (monoidAssoc   :: AssocCheck m)
  quickCheck (monoidLeftId  :: IdCheck m)
  quickCheck (monoidRightId :: IdCheck m)


main :: IO ()
main = do
  checkMonoid @(Maybe String)
  checkMonoid @[String]

背后的主要TypeApplications是引擎蓋下Haskell是轉變態函數到函數,也采取類型作為參數( 參見更多在這里 ) -和常GHC負責搞清楚哪種類型的參數,以填補在TypeApplications@SomeType說“讓前面函數調用的第一個類型參數為SomeType “。

通過擁有forall m. 我確保GHC會做到以上幾點。 然后,當我調用checkMonoid ,我明確地傳遞了m的類型。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM