Haskell:从类型中检索第n个值,这是一个元组

时间:2017-12-09 19:49:15

标签: haskell

我正在尝试从导入的包中访问某个类型中的某些数据。

类型由(包作者)声明为:

newtype MultiBalanceReport =
  MultiBalanceReport ([DateSpan]
                     ,[MultiBalanceReportRow]
                     ,MultiBalanceReportTotals
                     )

我尝试使用类似函数提取类型中的第一个列表:

getDates :: MultiBalanceReport -> [DateSpan]
getDates (date,_,_) = date

但是当我使用该函数时,编译器会抱怨类型不相同:

• Couldn't match expected type ‘MultiBalanceReport’
              with actual type ‘([DateSpan], t7, t8)’

我觉得编译器只是不知道MultiBalanceReport类型的内部细节?我没有导入正确定义类型的包吗?

我是Haskell的新手,很抱歉,如果我使用错误的命名法来描述我的问题。

3 个答案:

答案 0 :(得分:4)

您需要在模式匹配中包含newtype

getDates :: MultiBalanceReport -> [DateSpan]
getDates (MultiBalanceReport (date,_,_)) = date

答案 1 :(得分:4)

$ cat t5.cpp #include <CL/opencl.h> #include <stdio.h> #include <stdlib.h> #define TILE_WIDTH 16 #define DS 1024 const char source[] = "__kernel void matrix_multiply(__global float *A, __global float *B," " __global float *C, int width)" "{" " __local float Ashare[TILE_WIDTH][TILE_WIDTH];" " __local float Bshare[TILE_WIDTH][TILE_WIDTH];" " int bx = get_group_id(0);" " int by = get_group_id(1);" " int tx = get_local_id(0);" " int ty = get_local_id(1);" " int row = by * TILE_WIDTH + ty;" " int col = bx * TILE_WIDTH + tx;" " float result = 0;" " for (int m = 0; m < width / TILE_WIDTH; m++) {" " Ashare[ty][tx] = A[(row * width) + (m * TILE_WIDTH) + tx];" " Bshare[ty][tx] = B[(((m * TILE_WIDTH) + ty) * width) + col];" " barrier(CLK_LOCAL_MEM_FENCE); " " for (int k = 0; k < TILE_WIDTH; k++) {" " result += Ashare[ty][k] * Bshare[k][tx];" " }" " barrier(CLK_LOCAL_MEM_FENCE); " " }" " C[(row * width) + col] = result;" "};" ; int main(int argc, char *argv[]) { cl_platform_id platform; cl_device_id device; cl_context context; cl_command_queue queue1, queue2; cl_program program; cl_mem mem1, mem2, mem3; cl_kernel kernel; cl_int err; err = clGetPlatformIDs(1, &platform, NULL); if (err != CL_SUCCESS) {printf("%d: %d\n", __LINE__, err); return -1;} err = clGetDeviceIDs(platform, CL_DEVICE_TYPE_ALL, 1, &device, NULL); if (err != CL_SUCCESS) {printf("%d: %d\n", __LINE__, err); return -1;} context = clCreateContext(NULL, 1, &device, NULL, NULL, NULL); queue1 = clCreateCommandQueue(context, device, CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE, NULL); const char *sources[1] = {source}; program = clCreateProgramWithSource(context, 1, sources, NULL, &err); if (err != CL_SUCCESS) {printf("%d: %d\n", __LINE__, err); return -1;} err = clBuildProgram(program, 1, &device, "-D TILE_WIDTH=16", NULL, NULL); if (err == CL_BUILD_PROGRAM_FAILURE) { // Determine the size of the log size_t log_size; clGetProgramBuildInfo(program, device, CL_PROGRAM_BUILD_LOG, 0, NULL, &log_size); // Allocate memory for the log char *log = (char *) malloc(log_size); // Get the log clGetProgramBuildInfo(program, device, CL_PROGRAM_BUILD_LOG, log_size, log, NULL); // Print the log printf("%s\n", log); } if (err != CL_SUCCESS) {printf("%d: %d\n", __LINE__, err); return -1;} mem1 = clCreateBuffer(context, CL_MEM_READ_WRITE, DS*DS*sizeof(float), NULL, NULL); mem2 = clCreateBuffer(context, CL_MEM_READ_WRITE, DS*DS*sizeof(float), NULL, NULL); mem3 = clCreateBuffer(context, CL_MEM_READ_WRITE, DS*DS*sizeof(float), NULL, NULL); float *hdata = new float[DS*DS]; for (int i = 0; i < DS*DS; i++) hdata[i] = 1; kernel = clCreateKernel(program, "matrix_multiply", &err); if (err != CL_SUCCESS) {printf("%d: %d\n", __LINE__, err); return -1;} const size_t gwork_size[2] = {DS,DS}; const size_t lwork_size[2] = {TILE_WIDTH,TILE_WIDTH}; int msize = DS; err = clSetKernelArg(kernel, 0, sizeof(mem1), &mem1); if (err != CL_SUCCESS) {printf("%d: %d\n", __LINE__, err); return -1;} err = clSetKernelArg(kernel, 1, sizeof(mem2), &mem2); if (err != CL_SUCCESS) {printf("%d: %d\n", __LINE__, err); return -1;} err = clSetKernelArg(kernel, 2, sizeof(mem3), &mem3); if (err != CL_SUCCESS) {printf("%d: %d\n", __LINE__, err); return -1;} err = clSetKernelArg(kernel, 3, sizeof(msize), &msize); if (err != CL_SUCCESS) {printf("%d: %d\n", __LINE__, err); return -1;} err = clEnqueueWriteBuffer(queue1, mem1, CL_TRUE, 0, DS*DS*sizeof(float), hdata, 0, NULL, NULL); if (err != CL_SUCCESS) {printf("%d: %d\n", __LINE__, err); return -1;} err = clEnqueueWriteBuffer(queue1, mem2, CL_TRUE, 0, DS*DS*sizeof(float), hdata, 0, NULL, NULL); if (err != CL_SUCCESS) {printf("%d: %d\n", __LINE__, err); return -1;} err = clEnqueueNDRangeKernel(queue1, kernel, 2, NULL, gwork_size, lwork_size, 0, NULL, NULL); if (err != CL_SUCCESS) {printf("%d: %d\n", __LINE__, err); return -1;} err = clEnqueueReadBuffer(queue1, mem3, CL_TRUE, 0, DS*DS*sizeof(float), hdata, 0, NULL, NULL); if (err != CL_SUCCESS) {printf("%d: %d\n", __LINE__, err); return -1;} for (int i = 0; i < DS*DS; i++) if (hdata[i] != DS) {printf("error at %d, was %f, should be %f\n", i, hdata[i], (float)DS); return 1;} printf("success!\n"); return 0; } $ g++ -I/usr/local/cuda/include t5.cpp -o t5 -lOpenCL $ ./t5 success! $ 是带有构造函数的数据类型,因此您需要首先从构造函数newtype解包元组:< / p>

MultiBalanceReport

答案 2 :(得分:3)

你真的很亲近。您在元组类型上进行了模式匹配,但实际值是MultiBalanceReport包含一个元组。

getDates :: MultiBalanceReport -> [DateSpan]
getDates (MultiBalanceReport (date,_,_)) = date