我正在尝试破解haskell中newtype的记录语法,当newtype中有一个函数时,我的理解就会中断。考虑这个简单的例子
newtype C a b = C { getC :: (a -> b) -> a }
根据我的推理,C是一个在其构造函数中接受函数和参数的类型。 所以,
let d1 = C $ (2 *) 3
:t d1
也提供了
d1 :: Num ((a -> b) -> a) => C a b
再次检查一下,我做了:t getC d1
,显示了这个
getC d1 :: Num ((a -> b) -> a) => (a -> b) -> a
如果我尝试getC d1
,为什么会出错? getC
应返回函数及其参数或至少应用参数。
我不能拥有newtype C a b = C { getC :: (a->b)->b } deriving (Show)
,因为这没有意义!
答案 0 :(得分:3)
根据我的推理,C是一种接受函数和参数的类型
怎么样?构造函数只有一个参数。 Newtypes总是只有一个构造函数,只有一个参数。
类型C,otoh,有两个类型参数。但这与您可以应用于构造函数的参数数量无关。
答案 1 :(得分:2)
总是很好的是要强调Haskell有两个完全独立的命名空间,类型语言和值语言。在你的情况下,有
import win32ui
from pywin.mfc import object
import dde
class MySystemTopic(object.Object):
def __init__(self):
object.Object.__init__(self, dde.CreateServerSystemTopic())
def Exec(self, cmd):
print "System Topic asked to exec", cmd
class MyOtherTopic(object.Object):
def __init__(self, topicName):
object.Object.__init__(self, dde.CreateTopic(topicName))
def Exec(self, cmd):
print "Other Topic asked to exec", cmd
class MyRequestTopic(object.Object):
def __init__(self, topicName):
topic = dde.CreateTopic(topicName)
topic.AddItem(dde.CreateStringItem(""))
object.Object.__init__(self, topic)
def Request(self, aString):
print "Request Topic sent: ", aString
a="UP0 DN145800001 UMusb DMfm AZ040 EL005 SNNO SATELLITE"
print a
return(a)
server = dde.CreateServer()
server.AddTopic(MyRequestTopic("Tracking"))
server.Create('Orbitron')
while 1:
win32ui.PumpWaitingMessages(0, -1)
,它以类型语言存在。它需要两种类型C :: * -> * -> *
,a
(种类b
)并将它们映射到类型*
(也属于C a b
类型)。*
,它以值语言存在。它需要一个C :: ((a->b) -> a) -> C a b
函数(f
类型)并将其映射到值(a->b) -> a
(类型为C f
)。如果你有
,也许不会那么混乱C a b
但是因为对于newtype总是只有一个值构造函数(并且只有一个类型构造函数),所以将它们命名为相同是有意义的。
newtype CT a b = CV ((a->b) -> a)
是一个值构造函数,它接受一个函数,句号。该函数将具有签名CV
,即其参数也是一个函数,但就(a->b) -> a
而言,这并不重要。
实际上,CT
和data
声明使用newtype
符号有点不对,因为它并不意味着左右两侧的内容“相同” - 不能,因为他们甚至不属于同一种语言。有一种替代语法可以更好地表达关系:
=
至于你试图构建的那个值
{-# LANGUAGE GADTs #-} data CT :: * -> * -> * where CV :: ((a->b) -> a) -> CT a b
这里你不将“函数和参数”传递给let d1 = CV $ (\x->(2*x)) 3
。您实际上做了什么 1 ,您将函数CV
应用于值\x->2*x
(可能还写了3
)并将该数字传递给{{ 1}}。但正如我所说,6
期望一个功能。然后发生的是,GHC试图将CV
解释为一个函数,它给出了伪约束CV
。这意味着:“如果6
是数字类型,那么......”。当然,不是数字类型so the rest doesn't make sense either。
1 这是因为Num ((a->b) -> a)
具有最低优先级,即表达式(a->b)->a
实际上被解析为$
,或等效{{1} }} 子>