或者,换句话说,是否需要添加如下所述的约束?
工作代码,函数 f 的最小类型声明:
data ZeroPositive = Zero | Positive Int deriving Show
f :: [Int] -> [ZeroPositive]
f [] = []
f (0:xs) = Zero:(f xs)
f (x:xs) = (Positive x):(f xs)
main = putStrLn . show $ f [0,2]
结果:
[Zero,Positive 2]
破解代码,无用约束 ZeroPositive :
data ZeroPositive = Zero | Positive Int deriving Show
f :: ZeroPositive => [Int] -> [ZeroPositive]
f [] = []
f (0:xs) = Zero:(f xs)
f (x:xs) = (Positive x):(f xs)
main = putStrLn . show $ f [0,2]
结果:
99.hs:3:7:
Couldn't match expected type `ZeroPositive' with actual type `[t0]'
In the pattern: []
In an equation for `f': f [] = []
99.hs:3:12:
Couldn't match expected type `[Int] -> [ZeroPositive]'
with actual type `[a0]'
In the expression: []
In an equation for `f': f [] = []
...
99.hs:6:32:
Couldn't match expected type `ZeroPositive' with actual type `[t0]'
In the first argument of `f', namely `[0, 2]'
In the second argument of `($)', namely `f [0, 2]'
In the expression: putStrLn . show $ f [0, 2]
答案 0 :(得分:5)
此应该是一个错误,因为ZeroPositive
是一种数据类型,而不是一个类,因此不允许作为约束。
然而,你得到的奇怪的错误信息,是因为你使用的是具有a bug的旧GHC版本(如果我没记错的话, GHC 7.4 GHC 7.6,获得了ConstraintKinds
扩展程序通常正常工作,因此在语法中的更多相同位置允许=>
和->
,这使得=>
将->
视为@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
selectUsers = new ArrayList<SelectUser>();
resolver = getContentResolver();
contacts_list = (ListView) findViewById(R.id.contacts_list);
phones = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC");
LoadContact loadContact = new LoadContact();
loadContact.execute();
}
class LoadContact extends AsyncTask<Void, Void, Void> {
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected Void doInBackground(Void... voids) {
// Get Contact list from Phone
if (phones != null) {
Log.e("count", "" + phones.getCount());
if (phones.getCount() == 0) {
}
while (phones.moveToNext()) {
String id = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.CONTACT_ID));
String selected_name = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
String phoneNumber = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
String EmailAddr = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA));
String image_thumb = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.PHOTO_THUMBNAIL_URI));
try {
if (image_thumb != null) {
bit_thumb = MediaStore.Images.Media.getBitmap(resolver, Uri.parse(image_thumb));
} else {
Log.e("No Image Thumb", "--------------");
}
} catch (IOException e) {
e.printStackTrace();
}
SelectUser selectUser = new SelectUser();
selectUser.setThumb(bit_thumb);
selectUser.setName(selected_name);
selectUser.setPhone(phoneNumber);
Cursor emailCursor = resolver.query(ContactsContract.CommonDataKinds.Email.CONTENT_URI, null, ContactsContract.CommonDataKinds.Email.CONTACT_ID + " = ?", new String[] { id }, null);
while (emailCursor.moveToNext()) {
emails = emailCursor.getString(emailCursor.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA));
System.out.println("Email : " + emails);
selectUser.setEmail(emails);
}
emailCursor.close();
selectUser.setCheckedBox(false);
selectUsers.add(selectUser);
}
} else {
Log.e("Cursor close 1", "----------------");
}
//phones.close();
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
adapter = new SelectUserAdapter(selectUsers, MainActivity.this);
contacts_list.setAdapter(adapter);
// Select item on listclick
contacts_list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
Log.e("search", "here---------------- listener");
data = selectUsers.get(i);
String phoneNumber = data.getPhone();
String email = data.getEmail();
String name = data.getName();
Intent i1 = new Intent(MainActivity.this, SingleContact.class);
i1.putExtra("name", name);
i1.putExtra("phone_number", phoneNumber);
i1.putExtra("email", email);
startActivity(i1);
}
});
contacts_list.setFastScrollEnabled(true);
}
}
将实际数据类型而不是约束放在其左侧。
答案 1 :(得分:4)
我不明白你得到的错误; ØrjanJohansen的回答给出了合理的解释。真正的问题是:只要类型签名指示a => b
,a
就应该是约束。在标准Haskell中,这意味着a
看起来像C t
,其中C
是类的名称,t
是类型变量。在格拉斯哥哈斯克尔,约束可以更丰富。但是,在任何情况下,数据和约束都是完全不同的类型(在一般意义上它们具有不同的类型),因此您根本无法将数据类型用作上下文。