簡體   English   中英

無法匹配Haskell中的多態類型

[英]Could not match polymorphic type in haskell

我不確定為什么下面的k4不起作用,而當k3起作用時,為什么它的多態性足夠。 ghci的錯誤是

 • Couldn't match type 'K' a0 a0' with 'End K'' Expected type: K' a0 a0 -> K'' aa 
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE GADTs #-}
#!/usr/bin/env stack
-- stack --install-ghc --resolver lts-8.21 runghc --package http-conduit --package lens
{-# LANGUAGE ExistentialQuantification, RankNTypes #-}

module YonedaLan where

type End g = forall a. g a a 

data K'  b c = K'
data K'' b c = K''

k1 :: () -> End K'
k1 x = K'

k2 :: End K' -> End K''
k2 x = case x of (K') -> K''

k3 :: () -> End K''
k3 x = k2 ( k1 x)

k4 :: () -> End K''
k4 = k2 . k1

除了不寫自由的風格外,還有一些最佳實踐來解決這個問題嗎?

問題在於,GHC類型系統永遠不會將類型變量實例化為多態類型。 這樣做將需要類型系統中的難以置信。

在您的具體示例中,我們有

(.) :: (b->c) -> (a->b) -> (a->c)

然后鍵入check k2 . k1 k2 . k1我們需要實例化b ~ End K' ,這是一個多態類型。

一個典型的解決方法是使End K'成為包裹多態類型的單態類型。 例如

newtype End g = End { unEnd :: forall a. g a a }

付出的代價是在每次使用時明確包裝/拆開End g類型的值。 利用GHC的“安全脅迫”也可以緩解這種情況。

注意,其他一些語言(例如Agda,Coq,Idris)可以很好地處理您的代碼(適當翻譯),因為它們具有強制性類型系統。 但是,他們的推理機制與Haskell不同-難以置信使它變得更加困難。 有時(如果不是經常的話),類型推斷引擎找不到隱式類型參數,必須顯式提供類型。

暫無
暫無

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

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