是否有可能在Haskell 98中获得无限类错误?

时间:2015-04-29 16:29:42

标签: haskell functional-programming ocaml type-inference unification

我正在为一种新的函数式编程语言实现一种类型的系统,我目前正在编写这两种函数来统一它。有两种情况需要考虑:

+---------+---------+-------------------------------------------------------+
|   k1    |   k2    |                        action                         |
+=========+=========+=======================================================+
|   var   |   var   |                  k1 := k2 ^ k2 := k1                  |
+---------+---------+-------------------------------------------------------+
|   var   | non var |             if (!occurs(k1, k2)) k1 := k2             |
+---------+---------+-------------------------------------------------------+
| non var |   var   |             if (!occurs(k2, k1)) k2 := k1             |
+---------+---------+-------------------------------------------------------+
| non var | non var | ensure same name and arity, and unify respective args |
+---------+---------+-------------------------------------------------------+
  1. k1k2都是变量时,它们会相互实例化。
  2. 当只有k1是变量时,如果k2 k1 k2 k2 {{}}},则k1k2实例化。
  3. 当只有k1是变量时,如果k1 k2 let f x = f Dim pageUrl As String = HttpContext.Current.Request.Url.AbsolutePath Protected Sub Page_Load(sender As Object, e As System.EventArgs) Handles Me.Load Dim strLanguage As String = Session("Language") If Not IsPostBack Then Response.Redirect(String.Format("{0}?Language={1}", pageUrl, strLanguage)) End If Response.Write(String.Format("{0}?Idioma={1}", pageUrl, strLanguage)) End Sub {{}}},则If IsPostBack Then Dim pageUrl As String = HttpContext.Current.Request.Url.AbsolutePath Protected Sub Page_Load(sender As Object, e As System.EventArgs) Handles Me.Load Dim strLanguage As String = Session("Language") If Not IsPostBack Then If Request.QueryString("Language") Is Nothing Then Response.Redirect(String.Format("{0}?Language={1}", pageUrl, strLanguage)) End If Else If Not Request.QueryString("Language") Is Nothing Then Response.Redirect(String.Format("{0}?Language={1}", pageUrl, strLanguage)) End If End If Response.Write(String.Format("{0}?Language={1}", pageUrl, strLanguage)) End Sub 实例化。
  4. 否则,我们会检查private void sendNotification(int distance, ViewObject viewObject) { Intent notificationIntent = new Intent(getApplicationContext(), MainActivity.class); notificationIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP); notificationIntent.putExtra("path", viewObject.getPath()); TaskStackBuilder stackBuilder = TaskStackBuilder.create(this); stackBuilder.addParentStack(MainActivity.class); stackBuilder.addNextIntent(notificationIntent); PendingIntent notificationPendingIntent = stackBuilder.getPendingIntent(Integer.parseInt(viewObject.getRefId()), PendingIntent.FLAG_UPDATE_CURRENT); NotificationCompat.BigTextStyle bigText = new NotificationCompat.BigTextStyle(); bigText.bigText(String.format(getString(R.string.notification), viewObject.getTitle())); bigText.setBigContentTitle(getString(R.string.hello)); NotificationCompat.Builder builder = new NotificationCompat.Builder(this); builder.setSmallIcon(R.drawable.ic_wald_poi) .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.ic_poi)) .setColor(getResources().getColor(R.color.primary)) .setContentTitle(getString(R.string.hello)) .setContentIntent(notificationPendingIntent) .setContentText(String.format(getString(R.string.notification), viewObject.getTitle())) .setDefaults(Notification.DEFAULT_ALL) .setStyle(bigText); builder.setAutoCancel(true); NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); mNotificationManager.notify(0, builder.build()); } var deptList = dr.ReadAllDepartment(); departmentCombobox.DisplayMemberPath = "DepartmentName"; departmentCombobox.SelectedValuePath = "DepartmentId"; departmentCombobox.ItemsSource = deptList; nameTextBox.Text = departmentCombobox.SelectedValue.ToString(); 是否具有相同的名称和arity,并统一各自的参数。
  5. 对于第二和第三种情况,我们需要实施发生检查,这样我们就不会陷入无限循环。但是,我怀疑程序员是否能够构建无限种类。

    在Haskell中,构建无限类型很容易:

    {{1}}

    然而,无论我多么努力,我都无法构建无限种类。请注意,我没有使用任何语言扩展。

    我问这个的原因是因为如果根本不可能构建一个无限种类,那么我甚至不打算在我的类系统中实现类型的检查。

2 个答案:

答案 0 :(得分:34)

data F f = F (f F)

在GHC 7.10.1上,我收到消息:

kind.hs:1:17:
    Kind occurs check
    The first argument of ‘f’ should have kind ‘k0’,
      but ‘F’ has kind ‘(k0 -> k1) -> *’
    In the type ‘f F’
    In the definition of data constructor ‘F’
    In the data declaration for ‘F’

这条消息并没有说它是一种无限的类型,但实际上它就是发生检查失败时的情况。

答案 1 :(得分:26)

另一个简单的例子

GHCi, version 7.10.1: http://www.haskell.org/ghc/  :? for help
Prelude> let x = undefined :: f f

<interactive>:2:24:
    Kind occurs check
    The first argument of ‘f’ should have kind ‘k0’,
      but ‘f’ has kind ‘k0 -> k1’
    In an expression type signature: f f
    In the expression: undefined :: f f
    In an equation for ‘x’: x = undefined :: f f